สวิฟท์เป็นแม่?และมีลูกชายสองคน ?-
- ประเภทค่า ??♀️
- ประเภทอ้างอิง ?♂️
แต่ลักษณะของพวกเขาคืออะไร??♂️
พวกเขาประพฤติเหมือนหรือตรงกันข้ามกันหรือไม่? ?♂️
Swift เป็นภาษาการเขียนโปรแกรมแบบหลายกระบวนทัศน์ที่พัฒนาโดย Apple สำหรับ iOS, macOS, watchOS, tvOS, Linux และ z/OS?
เช่นเดียวกับภาษาการเขียนโปรแกรมเชิงวัตถุอื่น ๆ Swift มีคลาสเป็นหน่วยการสร้างซึ่งสามารถกำหนดวิธีการ คุณสมบัติ ตัวเริ่มต้น และสามารถสอดคล้องกับโปรโตคอล รองรับการสืบทอดและความหลากหลาย?
แต่เดี๋ยวก่อน รอ…???
Swift มี struct ด้วย และสามารถกำหนดเมธอด คุณสมบัติ ตัวเริ่มต้น และสามารถสอดคล้องกับโปรโตคอลได้โดยมีข้อยกเว้นเพียงข้อเดียวในการสืบทอด?
อะไร ตอนนี้สับสน!!! ???
ตอนนี้ มาเพิ่มความสับสนของคุณ:โครงสร้างไม่ได้เป็นเพียงประเภทค่าใน Swift Tuples และ enums เป็นประเภทค่าเช่นกัน คลาสไม่ใช่คลาสเดียวที่ใช้เป็นประเภทอ้างอิง ฟังก์ชันและการปิดเป็นประเภทอ้างอิงเช่นกัน แต่เพื่อเป็นสัญลักษณ์แห่งความโล่งใจ อย่างน้อยเราก็รู้จุดเน้นหลักและความเชี่ยวชาญเฉพาะด้านของการใช้งานประเภทนี้
จนถึงตอนนี้ เราเหลือเพียงความสับสนครั้งใหญ่เพียงครั้งเดียวกับการใช้โครงสร้างและคลาส?
ไปกันเถอะ ไปเคลียร์ความสับสนที่เกิดขึ้น?♂️
ตำแหน่งที่จัดเก็บ
มีที่เก็บข้อมูลสามประเภท:
- ลงทะเบียน ?
- กอง ☄️
- กอง ?
ออบเจ็กต์ที่มีอายุการใช้งานสั้นลงจะถูกเก็บไว้ในรีจิสเตอร์หรือสแต็ก และอ็อบเจ็กต์ที่มีอายุการใช้งานยาวนานกว่าจะถูกเก็บไว้ในฮีป
ประเภทค่าจะจัดเก็บเนื้อหาในหน่วยความจำที่จัดสรรในสแต็ก ดังนั้นเราสามารถพูดได้ว่าประเภทค่าได้รับการจัดสรรในสแต็กใน Swift ?
แต่มีความเข้าใจผิดทั่วไปเกี่ยวกับประเภทค่านิยม คุณเคยได้ยินไหม??♂️
ความเข้าใจผิดคือคนส่วนใหญ่คิดว่าประเภทค่าจะถูกเก็บไว้ในสแต็กเสมอ
❌❌รอสักครู่ — ไม่ใช่กรณีนี้เสมอไป ❌❌
ประเภทค่าสามารถเก็บไว้ในสแต็กได้เมื่อเป็นตัวแปรชั่วคราวหรือตัวแปรในเครื่อง แต่ถ้าประเภทค่าอยู่ในประเภทอ้างอิงล่ะ
ในสถานการณ์นี้ สามารถเก็บไว้ในหน่วยความจำฮีปได้ ?
ว้าว…เจ๋งไปเลย!!!?
ดังนั้นประเภทค่าจึงสามารถจัดเก็บในรีจิสเตอร์ สแต็ค หรือฮีปได้ ขึ้นอยู่กับอายุการใช้งาน ไม่ว่าจะเป็นอายุสั้นหรืออายุยืน หากเป็นตัวแปรโลคัล ก็สามารถอยู่ภายในสแต็กได้ และหากเป็นส่วนหนึ่งของคลาส ก็สามารถอยู่ภายในหน่วยความจำฮีปได้เช่นกัน✅
ในทางกลับกัน ประเภทการอ้างอิงจะจัดเก็บเนื้อหาในหน่วยความจำที่จัดสรรไว้ในหน่วยความจำฮีพ และตัวแปรจะเก็บเฉพาะการอ้างอิงไปยังตำแหน่งหน่วยความจำนั้นที่จัดเก็บข้อมูลจริง ??
มันทำงานอย่างไรสำหรับประเภทอ้างอิง ??
ดังนั้นสำหรับประเภทการอ้างอิง จึงเป็นเรื่องปกติที่จะมีตัวแปรหลายตัวที่อ้างอิงไปยังตำแหน่งหน่วยความจำเดียวกัน⚔️
เมื่ออินสแตนซ์ประเภทค่าถูกกำหนดให้กับตัวแปรหรือส่งผ่านไปยังฟังก์ชัน อินสแตนซ์จะถูกคัดลอกและกำหนดให้กับตัวแปรนั้น แต่ด้วยประเภทการอ้างอิง ระบบจะคัดลอกเฉพาะข้อมูลอ้างอิงเท่านั้น และตัวแปรใหม่จะมีข้อมูลอ้างอิงเดียวกันไปยังตำแหน่งหน่วยความจำเดียวกัน ?
ความแตกต่างในแง่ของความไม่แน่นอน
ตัวแปรสามารถมีได้สองสถานะ:
- ?♀ ️เปลี่ยนได้ ?♀
- ?️♂️ ไม่เปลี่ยนรูป ?️♂️
หากอินสแตนซ์ประเภทค่าถูกกำหนดให้กับตัวแปรที่ไม่เปลี่ยนรูป อินสแตนซ์นั้นก็จะเปลี่ยนไม่ได้เช่นกัน เป็นผลให้เราไม่สามารถทำการเปลี่ยนแปลงใด ๆ กับอินสแตนซ์นั้นได้?♂️
หากอินสแตนซ์ประเภทค่าถูกกำหนดให้กับตัวแปรที่เปลี่ยนแปลงได้ อินสแตนซ์นั้นจะทำให้อินสแตนซ์นั้นเปลี่ยนได้เท่านั้น ?♂️
แต่สิ่งต่าง ๆ โดยสิ้นเชิงสำหรับประเภทการอ้างอิง ตัวแปรและอินสแตนซ์ที่ได้รับมอบหมายนั้นแตกต่างกันโดยสิ้นเชิง หากเราประกาศตัวแปรที่ไม่เปลี่ยนรูปซึ่งมีการอ้างอิงถึงคลาส หมายความว่าการอ้างอิงที่เก็บไว้จะไม่เปลี่ยนแปลง เราไม่สามารถเปลี่ยนการอ้างอิงได้ และจะชี้ไปที่การอ้างอิงเดียวกันเสมอ ?
ประเภทโครงสร้าง
ค่าของประเภทโครงสร้างจะถูกเปรียบเทียบเพื่อความเท่าเทียมกันในแง่ของคุณลักษณะหรือองค์ประกอบ เราสามารถพูดได้ว่าประเภทค่าเท่ากับอีกประเภทหนึ่งก็ต่อเมื่อแอตทริบิวต์ที่เกี่ยวข้องทั้งหมดเท่ากัน ???
อืม...คำแรงเกินไป...หมายความว่าไง???
สมมติว่าเรามี บุคคล ประเภทค่าที่มีแอตทริบิวต์เช่น firstName และ นามสกุล
struct Person {
var firstName: String
var lastName: String
}
var person1 = Person(firstName: "foo", lastName: "bar")
var person2 = Person(firstName: "foo", lastName: "bar")
ที่นี่ทั้ง person1 &บุคคล2 อินสแตนซ์มีค่าเดียวกันสำหรับ firstName (“foo”) และ นามสกุล (“บาร์”) . ตามความเข้าใจของเรา เราสามารถพูดได้ว่าอินสแตนซ์ทั้งสองมีค่าเท่ากันเนื่องจากแอตทริบิวต์ (firstName &นามสกุล ) มีค่าเท่ากัน
แต่ไม่ได้จำกัดอยู่แค่เพียงกรณีนี้เท่านั้น:ในอนาคต จะมีบุคคลสองคนที่มีค่าเท่ากับ firstName &นามสกุล จะเท่าเทียมกัน
ตามความเข้าใจของเราจนถึงจุดนี้ เราสามารถพูดได้ว่า:
ประเภทค่าไม่มีข้อมูลประจำตัว ดังนั้นจึงไม่มีการอ้างอิงถึงค่าเหล่านี้ ประเภทค่าไม่มีตัวตน
อะไร พูดได้ยังไงเนี่ย????
var myAge: Int = 21
var friendAge: Int = 21
ทั้ง myAge &friendAge เป็นตัวแปรประเภทจำนวนเต็มที่มีค่า 21
เราแยกความแตกต่างออกจากกันได้ไหม? ?
ไม่ เพราะมันมีค่าเท่ากัน?
ตัวแปรจำนวนเต็มที่มีค่า 21 จะต้องไม่แตกต่างจากตัวแปรจำนวนเต็มตัวอื่นซึ่งมีค่าเท่ากับ 21 เช่นกัน ง่ายๆ แค่นั้นเอง ???
การไม่มีอัตลักษณ์ทำให้เกิดข้อได้เปรียบอีกประการหนึ่ง:ถ้าคุณคิดในทางปฏิบัติ คุณสามารถจินตนาการได้ว่าคุณไม่มีตัวตน จากนั้นใครก็ตามที่มีลักษณะเหมือนกันสามารถแทนที่หรือแทนที่คุณได้ ???
เช่นเดียวกับที่เราสามารถคิดสำหรับเราในฐานะมนุษย์ได้เช่นกัน ถ้าฉันไม่มีตัวตน ใครก็ตามที่มีลักษณะเหมือนกันสามารถแทนที่ฉันได้??? ดีสำหรับเราที่เรามีเอกลักษณ์เฉพาะตัว ไม่เช่นนั้นจะมีความเสี่ยงสูงต่อการดำรงอยู่ของเราหรือไม่
แต่สำหรับประเภทค่านิยม พวกเขาไม่มีอัตลักษณ์และเป็นประโยชน์ต่อพวกเขา ?
ประโยชน์ของการใช้ประเภทมูลค่ามีอะไรบ้าง
? ไม่มีเงื่อนไขการแข่งขันและการหยุดชะงัก:?
สำหรับประเภทค่าในสภาพแวดล้อมแบบมัลติเธรด เธรดหนึ่งไม่สามารถเปลี่ยนสถานะของอินสแตนซ์ในขณะที่เธรดอื่นกำลังใช้งานอยู่ เราพูดได้เลยว่าจะไม่มีสภาพการแข่งขันหรือการชะงักงัน
⚔️ ไม่มีรอบการกัก:⚔️
เมื่อมีอินสแตนซ์ประเภทการอ้างอิงสองอินสแตนซ์ที่มีการอ้างอิงที่แข็งแกร่งถึงกันและป้องกันไม่ให้ถูกจัดสรรคืนจากหน่วยความจำ เรียกว่าวงจรการคงไว้ เนื่องจากประเภทค่าใช้ไม่ได้กับข้อมูลอ้างอิง เราจึงกล่าวได้ว่าจะไม่มีวงจรการรักษาสำหรับประเภทค่า
???? การนับการอ้างอิงอัตโนมัติ:????
สำหรับประเภทการอ้างอิง Swift ใช้การนับการอ้างอิงอัตโนมัติเพื่อติดตามวัตถุที่ใช้งานอยู่หรือที่ใช้งานอยู่ทั้งหมด และจัดสรรคืนอินสแตนซ์เฉพาะเมื่อไม่มีการอ้างอิงที่รัดกุมแล้วเท่านั้น หากเราคิดสักนิด เราสามารถพูดได้ว่าเป็นการปฏิบัติการที่หนักหน่วงเพราะ Swift Runtime จำเป็นต้องติดตามวัตถุอยู่เสมอ แต่เนื่องจากประเภทค่าถูกจัดสรรในสแต็ก จึงไม่จำเป็นต้องมี ARC จึงถูกและเร็วกว่า??.
แต่เดี๋ยวก่อน...มันจัดการหน่วยความจำสำหรับ Array, Dictionary และ String อย่างไร
เนื่องจากเราไม่สามารถทราบขนาดที่แท้จริงของอาร์เรย์ พจนานุกรม และสตริงในขณะคอมไพล์ได้ จึงไม่มีขอบเขตสำหรับการจัดสรรในเวลาคอมไพล์ แม้ว่าจะเป็นประเภทค่าภายใน แต่ก็ไม่สามารถจัดสรรในสแต็กได้ พวกเขาจำเป็นต้องได้รับการจัดสรรในหน่วยความจำฮีป และในการจัดการสิ่งนี้ Swift มาพร้อมกับ คัดลอกในการเขียน .?
แต่นี่คืออะไร??
เมื่อเราบอกว่าอินสแตนซ์หนึ่งเป็นสำเนาของอีกอินสแตนซ์หนึ่ง นี่หมายความว่าอินสแตนซ์เหล่านั้นเหมือนกัน มีค่าเท่ากัน แต่ใน Swift สำหรับประเภทข้างต้นเหล่านี้ (อาร์เรย์ พจนานุกรม สตริง ฯลฯ) สำเนาจริงจะถูกสร้างขึ้นบนฮีปก็ต่อเมื่ออินสแตนซ์ถูกกลายพันธุ์เท่านั้น นี่เรียกว่าเทคนิคการเพิ่มประสิทธิภาพสำหรับประเภทค่า???
บทสรุป
ไม่มีกฎตายตัวที่กำหนดว่าเมื่อใดควรใช้ประเภทค่าและเมื่อใดควรใช้ประเภทอ้างอิง ประเภทค่ามีข้อดีเฉพาะเหนือประเภทอ้างอิงและในทางกลับกัน ทั้งคู่มีเอกลักษณ์ในแบบของตัวเอง ขึ้นอยู่กับความต้องการของคุณและสิ่งที่คุณพยายามทำให้สำเร็จ คุณควรรู้ความหมายของโค้ดของคุณ เพราะคุณรู้แค่โค้ดของคุณดีที่สุดเท่านั้น ดังนั้นจึงขึ้นอยู่กับคุณที่จะเลือก คุณมีอิสระเต็มที่
ดังนั้นแทนที่จะต่อสู้กับประเภทมูลค่ากับประเภทอ้างอิง ให้ใช้อย่างชาญฉลาด
??? ไชโย !!! ขอบคุณสำหรับการอ่าน!! ???
✅✅✅คุณสามารถหาฉันได้ที่ ทวิตเตอร์ .✅✅✅