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

Dup vs Clone ใน Ruby: เชี่ยวชาญเทคนิคการคัดลอกออบเจ็กต์

คุณรู้ไหมว่าคุณสามารถคัดลอกออบเจ็กต์ใน Ruby ได้? ไม่ chỉนั้น แตยังมีสองเมธอดที่แตกต่างกันสำหรับทำสิ่งนี้!

เมธอดเหล่านี้คือ:

  • dup
  • clone

เราจะสำรวจความต่างในหนึ่งพัก แตก่อน...

ทำไมคุณถึงอยาก clone ออบเจ็กต์?

ออบเจ็กต์หลายอย่างใน Ruby เป็น mutable (เปลี่ยนแปลงได้)

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

ตัวอย่าง.

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

วิธีหนึ่ง:

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

อีกวิธี:

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

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

Dup vs Clone ใน Ruby: เชี่ยวชาญเทคนิคการคัดลอกออบเจ็กต์

Frozen Objects (ออบเจ็กต์ที่ถูกแช่แข็ง)

Dup และ clone ไม่ใช่ alias ของกันและกันเหมือนเมธอด Ruby อื่นๆ (map/collect) มีความต่างเล็กน้อยระหว่างพวกมัน

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

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

อะไรคือแอตทริบิวต์ของออบเจ็กต์?

  • frozen status (สถานะการแช่แข็ง)
  • tainted status (สถานะที่ปนเปื้อน)
  • singleton class

ตัวอย่าง:

a = Object.new.freeze
b = a.dup
b.frozen? # false
b = a.clone
b.frozen? # true

Ruby 2.4 รวมตัวเลือกสำหรับ clone เพื่อเพิกเฉยสถานะ frozen ของออบเจ็กต์ที่ clone

ตัวอย่าง:

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

Deep vs Shallow Copying

การคัดลอกออบเจ็กต์มีรายละเอียดมากกว่าที่คิด

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

นี่หมายความว่าออบเจ็กต์ที่อยู่ภายในออบเจ็กต์อื่น จะไม่ถูกคัดลอก

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

ถ้าคุณมีอาร์เรย์ของสตริง แค่อาร์เรย์จะถูกคัดลอก ไม่ใช่สตริงเอง

ดูด้วยตัวเอง:

original = %w(apple orange banana)
copy = original.clone
original.map(&:object_id) # [23506500, 23506488, 23506476]
copy.map(&:object_id)   # [23506500, 23506488, 23506476]

Object IDs เหมือนกันแม้หลัง clone อาร์เรย์ ดังนั้นเรามีสตริงเดียวกัน

คุณแก้ได้ด้วย:

strings.clone.map(&:clone)

สิ่งนี้ทำให้ทั้งอาร์เรย์และสตริงถูก clone แตสังเกตว่านี้ไปได้แค่ระดับเดียว (one level deep) คุณลอง deep_dup method จาก ActiveSupport เป็นทางเลือก

สรุป

คุณได้เรียนรู้เกี่ยวกับการ clone ออบเจ็กต์ใน Ruby! รวมถึงความต่างระหว่าง dup และ clone methods และ shallow copy vs deep copy

ขอบคุณที่อ่านครับ!