Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> สมาร์ทโฟน >> iPhone

เข้าใจ Swift: เปรียบเทียบ Value Types และ Reference Types

Swift เป็นแม่ ? และมีลูกชาย 2 คน ?-

  • Value Type ??‍♀️
  • Reference Type ?‍♂️

แต่ลักษณะเฉพาะของพวกเขาคืออะไร??‍♂️

พวกเขาเหมือนกันหรือตรงข้ามกัน? ?‍♂️

Swift เป็นภาษา Multi-paradigm ที่ Apple พัฒนาสำหรับ iOS, macOS, watchOS, tvOS, Linux, z/OS ?

เหมือน OOP อื่นๆ Swift มี Classes เป็น Building Blocks 定义 Methods, Properties, Initializers, Conform Protocols, Support Inheritance & Polymorphism ?

แต่นี่... ?

Swift มี Structs ด้วย และ Define Methods, Properties, Initializers, Conform Protocols ได้ มีข้อยกเว้นแค่ Inheritance ?

เอ๊ะ! สับสนแล้ว!!! ???

เพิ่มความสับสน: Structs ไม่ใช่ Value Types เพียงอย่างเดียวใน Swift Tuples และ Enums ก็เป็น Value Types Classes ก็ไม่ใช่ Reference Type เพียงอย่างเดียว Functions และ Closures ก็เป็น Reference Types แต่บอกได้เลยว่าเรารู้ Focus และ Specialization ของแต่ละ Type แล้ว ?

จนตอนนี้เหลือความสับสนใหญ่แค่ Structs และ Classes ?

ไปล้างความสับสนกันเลย?‍♂️

Storage Locations (ตำแหน่งจัดเก็บ)

มี Storage 3 ประเภท:

  • Register ?
  • Stack ☄️
  • Heap ?

Object ที่อายุสั้นอยู่ใน Register หรือ Stack อายุยาวอยู่ใน Heap ?

Value Type เก็บ Contents ใน Memory ที่ Allocate ใน Stack บอกได้ว่า Value Types Allocate ใน Stack ใน Swift ?

แต่มี Misconception เกี่ยว Value Types ได้ยินไหม??‍♂️

Misconception คือส่วนใหญ่คิดว่า Value Types เก็บใน Stack เสมอ

❌❌ รอสักครู่ — ไม่ใช่เสมอไป ❌❌

Value Types เก็บใน Stack เมื่อเป็น Temporary หรือ Local Variables แต่ถ้า Value Type อยู่ใน Reference Type?

สถานการณ์นี้เก็บใน Heap Memory ได้ ?

Wow... น่าสนใจ!!!?

Value Types เก็บใน Register, Stack, หรือ Heap ขึ้นกับ Lifespan สั้นหรือยาว ถ้าเป็น Local Variable อยู่ใน Stack ถ้าเป็นส่วนของ Class อยู่ใน Heap ได้ ✅

ด้านอื่น Reference Type เก็บ Contents ใน Memory ที่ Allocate ใน Heap และ Variable เก็บแค่ Reference ไปที่ Memory Location ที่ Data จริงเก็บ ?

Reference Type ทำงานยังไง?

สำหรับ Reference Type กรณีทั่วไปมี Variable หลายตัวถือ Reference ไป Memory Location เดียวกัน ⚔️

Value Type Instance Assign ให้ Variable หรือ Pass ให้ Function Instance จะถูก Copy และ Assign ให้ Variable นั้น แต่ Reference Type Copy แค่ Reference Variable ใหม่ถือ Reference เดียวไป Memory เดียวกัน ?

ความแตกต่างด้าน Mutability (ความสามารถในการเปลี่ยนแปลง)

Variable มี 2 สถานะ:

  • ?‍♀️ Mutable ?‍♀️
  • ?️‍♂️ Immutable ?️‍♂️

Value Type Instance Assign ให้ Immutable Variable Instance ก็กลายเป็น Immutable ไม่สามารถเปลี่ยน Instance นั้นได้ ?‍♂️

Value Type Instance Assign ให้ Mutable Variable ถึงทำให้ Instance Mutable ?‍♂️

แต Reference Type ต่างไปหมด Variable และ Instance ที่ Assign ต่างกัน ถ้าประกาศ Immutable Variable ถือ Reference ไป Class หมายถึง Reference ที่ถือจะไม่เปลี่ยน ไม่สามารถเปลี่ยน Reference ได้ จะชี้ Reference เดียวเสมอ ?

Structural Types (ประเภทโครงสร้าง)

Values ของ Structural Types เทียบ Equality ด้วย Attributes หรือ Elements บอกได้ว่า Value Type เท่ากันก็ต่อเมื่อ Attributes ตรงกันทั้งหมด ???

อืม... คำยากเกินไป... หมายถึงอะไร???

สมมติมี Person Value Type มี Attributes firstName และ lastName

struct Person { var firstName: String var lastName: String } var person1 = Person(firstName: "foo", lastName: "bar") var person2 = Person(firstName: "foo", lastName: "bar")

ทั้ง person1 & person2 เก็บค่า firstName ("foo") และ lastName ("bar") เหมือนกัน ตามความเข้าใจ 2 Instance นี้เท่ากัน เพราะ Attributes (firstName & lastName) เก็บค่าเดียวกัน

ไม่จำกัดแค่นี้: ในอนาคต Person Instance ใดๆ ที่เก็บค่า firstName & lastName เหมือนกัน จะเท่ากัน

ตามความเข้าใจจนถึงที่นี่ บอกได้ว่า:

Value Types ไม่มี Identity จึงไม่มี Reference ชี้พวกเขา Value Types ไม่มีใบหน้า ?

อะไร? ทำไมถึงบอกได้????

var myAge: Int = 21 var friendAge: Int = 21

ทั้ง myAge & friendAge เป็น Integer Variable ค่า 21

แยกแยะได้ไหม? ?

ไม่ได้ เพราะเก็บค่าเดียวกัน ?

Integer Variable ค่า 21 ไม่ต่างจาก Integer Variable อีกตัวที่ค่า 21 เหมือนกัน ง่ายแค่นั้น ???

ไม่มี Identity ให้ Value Types ข้อได้เปรียบ: คิดแบบปฏิบัติ หากไม่มี Identity ใครที่มีลักษณะเหมือนกันแทนที่คุณได้ ???

คิดเหมือนกันสำหรับมนุษย์ ถ้าผมไม่มี Identity ใครลักษณะเหมือนผมแทนที่ผมได้ ??? ดีที่เรามี Identity ไม่งั้นเสี่ยงต่อการมีอยู่ ?

แต่ Value Types ไม่มี Identity เป็นข้อได้เปรียบ ?

ข้อได้เปรียบของ Value Types?

? ไม่มี Race Conditions และ Deadlocks: ?

Value Types ใน Multi-threaded Environment ไม่可能让 Thread หนึ่ง Mutate State ของ Instance ขณะ Thread อื่นใช้ จึงไม่มี Race Conditions หรือ Deadlocks

⚔️ ไม่มี Retain Cycles: ⚔️

2 Reference Type Instances ถือ Strong References กัน ป้องกัน Deallocate จาก Memory เรียกว่า Retain Cycle Value Types ไม่ทำงานแบบ Reference จึงไม่มี Retain Cycles

?‍?‍?‍? Automatic Reference Counting: ?‍?‍?‍?

Reference Type Swift ใช้ ARC ติดตาม Object ที่ Live/Active Deallocate Instance เฉพาะตอนไม่มี Strong References อีก ถ้าคิดนิดหน่อย Heavy Operation เพราะ Swift Runtime ติดตาม Object ตลอด แต่ Value Types Allocate ใน Stack ไม่ต้อง ARC ถูกกว่า เร็วกว่า ??

แต... จัดการ Memory Array, Dictionary, String ยังไง??

เนื่องจากไม่รู้ Actual Size ของ Array, Dictionary, String ระหว่าง Compile Time ไม่มีโอกาส Allocate ใน Compile Time แม้เป็น Value Types ภายใน แต่ไม่ Allocate ใน Stack ได้ ต้อง Allocate ใน Heap Swift มี Copy on Write ?

แต่ это что такое??

พูดว่า Instance หนึ่ง Copy ของอีก Instance หมายถึงเหมือนกัน มีค่าเหมือนกัน แต่ใน Swift สำหรับ Type เหล่านี้ (Array, Dictionary, String, etc) Actual Copy ใน Heap ทำก็ต่อเมื่อ Instance Mutate เรียกว่า Performance Optimization Technique สำหรับ Value Types ???

สรุป

ไม่มี Hard Rule กำหนดเมื่อไหร่ใช้ Value Type หรือ Reference Type Value Types มีข้อได้เปรียบเฉพาะตัว Reference Types ก็เช่นกัน ทั้งคู่ Unique ตัวเอง ขึ้นกับ Requirements และเป้าหมาย คุณควรเข้าใจ Semantics ของโค้ดเพราะคุณรู้โค้ดตัวเองดีที่สุด เลือกได้อิสระ

แทนที่จะโต้เถียง Value Type vs Reference Type ใช้ทั้งคู่ฉลาดๆ

??? Cheers!!! ขอบคุณที่อ่าน!! ???

✅✅✅ หาผมได้ที่ Twitter. ✅✅✅