Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

Dup vs Clone ใน Ruby:การทำความเข้าใจความแตกต่าง

คุณรู้หรือไม่ว่าคุณสามารถคัดลอกวัตถุใน Ruby ได้? ไม่เพียงเท่านั้น แต่ยังมีสองวิธีในการทำเช่นนี้!

วิธีการเหล่านี้ :

  • dup
  • clone

เราจะสำรวจความแตกต่างในอีกสักครู่ แต่ก่อนอื่น…

ทำไมคุณถึงต้องการโคลนวัตถุ ?

วัตถุจำนวนมากใน Ruby สามารถเปลี่ยนแปลงได้ คุณสามารถเปลี่ยนได้

หากคุณต้องการเปลี่ยนวัตถุแต่เก็บสำเนาต้นฉบับไว้ จากนั้นคุณสามารถโคลนได้

ตัวอย่างเช่น

คุณอาจต้องการอาร์เรย์ที่มีองค์ประกอบทั้งหมดยกเว้นองค์ประกอบแรก

วิธีหนึ่งในการทำสิ่งนี้ :

a =[1,2,3,4,5]a[1..-1]# [2,3,4,5]

อีกวิธีหนึ่งก็คือ :

b =a.cloneb.shift# [1]b# [2,3,4,5]

ทั้งสองตัวอย่างช่วยให้คุณสามารถเก็บอาร์เรย์เดิมไว้ได้

Dup vs Clone ใน Ruby:การทำความเข้าใจความแตกต่าง

วัตถุแช่แข็ง

Dup &clone ไม่ใช่นามแฝงของกันและกันเหมือนกับที่เกิดขึ้นกับวิธี Ruby อื่น ๆ (แผนที่ / รวบรวม) ซึ่งมีความแตกต่างกันเล็กน้อย

สำรวจความเหมือนและความแตกต่าง ระหว่างสองสิ่งนี้ เป็นวิธีที่ดีในการปรับปรุงความเข้าใจของคุณ .

ทั้งสองวิธีคัดลอกวัตถุ ข้อแตกต่างคือ dup ไม่คัดลอกแอตทริบิวต์ของวัตถุ

แอตทริบิวต์ของวัตถุใด

  • สถานะหยุดนิ่ง
  • สถานะเสีย
  • ชั้นเดียว

นี่คือตัวอย่าง :

a =Object.new.freezeb =a.dupb.frozen?# falseb =a.cloneb.frozen?# จริง

Ruby 2.4 มีตัวเลือกสำหรับ clone เพื่อละเว้นสถานะแช่แข็งของวัตถุที่ถูกโคลน

ตัวอย่าง :

a.clone(freeze:true)a.clone(freeze:false)

การคัดลอกแบบลึกและตื้น

การคัดลอกวัตถุมีมากกว่าที่คิด

เมื่อคุณทำสำเนาด้วย dup หรือ clone , คุณกำลังทำสำเนาที่ตื้น .

ซึ่งหมายความว่าระบบจะไม่คัดลอกวัตถุที่อยู่ในวัตถุอื่น

กล่าวอีกนัยหนึ่ง :

หากคุณมีอาร์เรย์ของสตริง ระบบจะคัดลอกเฉพาะอาร์เรย์เท่านั้น ไม่ใช่สตริงเอง

ดูด้วยตัวคุณเอง:

ต้นฉบับ =%w(กล้วยส้มแอปเปิ้ล)copy =original.cloneoriginal.map(&:object_id)# [23506500, 23506488, 23506476]copy.map(&:object_id)# [23506500, 23506488, 23506476] 

รหัสอ็อบเจ็กต์จะเหมือนกันแม้หลังจากโคลนอาร์เรย์แล้ว ดังนั้นเราจึงมีสตริงเดียวกัน

คุณแก้ได้ด้วยสิ่งนี้:

strings.clone.map(&:clone)

ส่งผลให้ทั้งอาร์เรย์และสตริงถูกโคลน แต่สังเกตว่าการดำเนินการนี้ลึกเพียงระดับเดียวเท่านั้น คุณสามารถลองใช้วิธี deep_dup จาก ActiveSupport แทนได้

สรุป

คุณได้เรียนรู้เกี่ยวกับการโคลนวัตถุใน Ruby แล้ว! รวมความแตกต่างระหว่างวิธีการคัดลอก &โคลน และการคัดลอกแบบตื้นและแบบลึก

ขอบคุณสำหรับการอ่าน!