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

มาวิเคราะห์ความแตกต่างระหว่าง Generics และ Any type ใน Swift

Swift เป็นหนึ่งในภาษาที่พิมพ์ได้ดีที่สุดในปัจจุบัน ???

โอ้ เดี๋ยวก่อน!! หมายความว่าอย่างไรหากภาษานั้นปลอดภัยสำหรับการพิมพ์ ?

ภาษาที่ปลอดภัยสำหรับการพิมพ์ช่วยให้แน่ใจว่าการดำเนินการทำงานกับข้อมูลที่ถูกต้อง ณ จุดนั้นเสมอ✓

หากภาษามีความสามารถในการประกาศประเภทข้อมูลที่แตกต่างกัน (เช่น Int, Float, String, Array, Dictionary) และยังมีความสามารถในการตรวจสอบให้แน่ใจว่าตัวแปรที่ประกาศด้วยประเภทข้อมูลเฉพาะจะไม่มีลักษณะที่แตกต่างกัน ข้อมูลจึงเรียกว่าภาษาที่ปลอดภัยสำหรับการพิมพ์

ในภาษาที่ปลอดภัยสำหรับการพิมพ์ การตรวจสอบประเภทจะทำเสมอ อาจเกิดขึ้นในเวลาคอมไพล์หรือรันไทม์ขึ้นอยู่กับภาษา✅

ตอนนี้ Generics ใน Swift คืออะไร

Generics เป็นประเภทที่ปลอดภัยและช่วยให้เราเขียนฟังก์ชันและประเภทที่ยืดหยุ่นและนำกลับมาใช้ใหม่ได้ เมื่อใช้ Generics เราสามารถเขียนโค้ดที่ใช้ได้กับข้อมูลทุกประเภท เนื่องจาก Swift เป็นภาษาที่ปลอดภัยต่อการพิมพ์ โดยไม่ทำลายสิ่งนี้ เราจึงสามารถเขียนโค้ดทั่วไปเพื่อหลีกเลี่ยงการซ้ำซ้อนของโค้ดได้

มาดูตัวอย่างง่ายๆ กัน:อาร์เรย์คือคอลเล็กชันที่เรียงลำดับซึ่งสามารถเก็บข้อมูลประเภทเดียวกันได้ นั่นคือเหตุผลที่ในคำจำกัดความของ Array เราจะเห็นได้ว่าต้องใช้ องค์ประกอบ ทั่วไป ดังนั้น Array จะกลายเป็น คอลเล็กชันประเภททั่วไป .

ตกลง เย็น. แล้ว Swift ประเภทใดก็ได้คืออะไร ???

Swift ยังรองรับประเภทใดก็ได้ ตามชื่อที่ระบุ มันสามารถแสดงอินสแตนซ์ของประเภทใดก็ได้ เช่น struct, class, enum และประเภทฟังก์ชัน

แล้ว Objective C id และ Swift เหมือนกันหรือไม่

em> ?

ใน Swift 3 วัตถุประสงค์ C id พิมพ์แผนที่ไปยังประเภทใดก็ได้ของ Swift สิ่งนี้ช่วยปรับปรุงความเข้ากันได้ของ Swift และ Objective C

แต่อย่างไรและทำไม

ใน Swift 2 วัตถุประสงค์ C id ถูกแมปกับวัตถุใด ๆ ของ Swift วิธีนี้ใช้ได้ผลดีสำหรับกรณีส่วนใหญ่ แต่บางครั้งก็ส่งผลให้เกิดพฤติกรรมที่ไม่คาดคิด แนวคิดหลักอย่างหนึ่งใน Swift คือประเภทค่า และการทำแผนที่นี้ไม่ได้ทำให้แนวคิดนี้เหมาะสม

Swift เป็นเพียงภาษาใหม่สำหรับการพัฒนา iOS และ Objective C มีมานานหลายปีแล้ว แน่นอนว่าโครงการส่วนใหญ่ได้รับการพัฒนาใน Objective C เท่านั้น ในตอนนี้ ในการแปลงโปรเจ็กต์ Objective เป็นโปรเจ็กต์ Swift จำเป็นต้องมีข้อกำหนดว่าควรจะเชื่อมโยง Swift ประเภทใดก็ได้กับอ็อบเจ็กต์ Objective C

แต่นี่ไม่ใช่ปัญหาสำหรับคลาส Swift และประเภทค่า Swift เช่น Int, String, Float เพราะมีคู่ Objective C อยู่แล้ว ปัญหาเกิดขึ้นกับประเภทค่า Swift ที่ไม่มีคู่ของ Objective C

ดังนั้นเพื่อแก้ไขปัญหานี้ Objective C id type จะถูกแมปกับ Swift Any type✅✅✅

คำจำกัดความเพียงพอ ? มาถึงหัวข้อหลักกันเลย จากจุดข้างต้นดูเหมือนว่า Generics และ Any type จะเหมือนกัน แต่ใช่หรือไม่

ในระดับสูง สิ่งใดๆ อาจดูเหมือน Generics แต่มาลองค้นหาความแตกต่างกัน-???

เราทุกคนรู้ดีว่า กอง อยู่ในโครงสร้างข้อมูลใช่ไหม สแต็กเป็นโครงสร้างข้อมูลเชิงเส้นพื้นฐานที่การแทรกและการลบรายการจะเกิดขึ้นที่ปลายด้านหนึ่งเท่านั้น

ตอนนี้ เราจะนำโครงสร้าง Stack ไปใช้ใน Swift ขั้นแรก เราจะปรับใช้โดยใช้ Generics จากนั้นกับประเภทใดก็ได้

การติดตั้งใช้งานสแต็กโดยใช้ Generics:

การใช้งาน Stack ด้านบนนั้นใช้ Generics โครงสร้างใช้ประเภททั่วไปของ องค์ประกอบ รายการและใช้งานสแต็กโดยใช้รายการนั้น มาเริ่มดำเนินการกับ Generic Stack กัน:

ประกาศ Generic Stack ซึ่งสามารถเก็บองค์ประกอบประเภทจำนวนเต็มได้ เรากำลังผลักองค์ประกอบจำนวนเต็มไปที่สแต็ก ถึงจุดนี้ทุกอย่างก็ใช้ได้ดี

แต่ถ้าฉันต้องการผลักองค์ประกอบ float ไปไว้เหนือ genericStack?

มาวิเคราะห์ความแตกต่างระหว่าง Generics และ Any type ใน Swift

❌❌ อ๊ะ! คอมไพล์ผิดพลาด! ❌❌

การติดตั้งสแต็กโดยใช้ประเภทใดก็ได้:

ใน Stack Implementation นี้ อาร์เรย์ items สามารถเก็บองค์ประกอบประเภทใดก็ได้ เราไม่ได้ระบุประเภทข้อมูลที่แน่นอนของ items องค์ประกอบอาร์เรย์ในคำจำกัดความ มาทำขั้นตอนพื้นฐานแบบเดียวกันกับสแต็กนี้กัน:

ไม่มีปัญหาใช่ไหม ทุกอย่างทำงานได้ดีที่นี่ด้วย เริ่มแรก เราประกาศสแต็กและพุชอิลิเมนต์จำนวนเต็มสององค์ประกอบเข้าไป เมื่อเราเรียก show() เมธอด มันพิมพ์อาร์เรย์ที่แน่นอน [3, 4].

ตอนนี้ มาดันค่าทศนิยมเข้าไปกันเถอะ☄️

มาวิเคราะห์ความแตกต่างระหว่าง Generics และ Any type ใน Swift

✅✅ ไม่มีข้อผิดพลาด! ทุกอย่างทำงานได้ดี! ✅✅

แล้วเกิดอะไรขึ้นเบื้องหลัง ? ทำไมเราจึงไม่ได้รับข้อผิดพลาดใด ๆ ??? ?

Generics โดยทั่วไปจะบอกคอมไพเลอร์ว่า:

ฉันได้ประกาศประเภททั่วไปแล้ว และจะระบุประเภทที่แน่นอนให้คุณทราบในภายหลัง ฉันต้องการให้คุณใช้ประเภทนั้นทุกที่ที่ฉันระบุ

ประเภทใดก็ได้บอกคอมไพเลอร์โดยพื้นฐาน:

ไม่ต้องกังวลกับตัวแปรนี้ ไม่จำเป็นต้องใช้ประเภทใดๆ ที่นี่ ให้ฉันทำทุกอย่างที่อยากทำ

สามารถใช้ Generics เพื่อกำหนดฟังก์ชันที่ยืดหยุ่นได้ แต่คอมไพเลอร์ยังคงตรวจสอบประเภทของอาร์กิวเมนต์ ใช้หลบหลีกระบบประเภทไหนก็ได้

ในการประกาศสแต็คทั่วไป เรากำลังบอกคอมไพเลอร์ว่าสแต็กควรใช้ประเภทจำนวนเต็มเท่านั้น จากนั้นเมื่อเราพยายามแทรกองค์ประกอบประเภท float เข้าไป นั่นหมายความว่าเรากำลังทำผิดสัญญานั้น ดังนั้นจึงทำให้เกิดข้อผิดพลาดในการคอมไพล์ คาดเสมอว่าองค์ประกอบควรเป็นประเภทจำนวนเต็ม

แต่สำหรับกองใดก็ได้ เราไม่ได้รับข้อผิดพลาดเวลาคอมไพล์หรือรันไทม์ แม้ว่าเราจะเรียก show() เมธอด มันพิมพ์สแต็กเป็น [3, 4, 5.0] ซึ่งหมายความว่าสแต็กเก็บค่าประเภทจำนวนเต็มและจำนวนลอย ดังนั้นในสแต็กใดๆ ก็ตาม ไม่มีการจำกัดประเภท เราสามารถใส่ค่าประเภทใดก็ได้ลงไป (แต่มีความเป็นไปได้ที่จะมีข้อยกเว้นรันไทม์)

สรุป

ดังนั้น หากเราใช้ Generics เราก็สามารถเขียนฟังก์ชัน โครงสร้าง คลาส และโปรโตคอลที่ยืดหยุ่นได้โดยไม่กระทบต่อความปลอดภัยของประเภท Swift แต่ถ้าเราใช้ Any type เราก็เป็นนายแบบเรา เราจะทำอะไรก็ได้เกือบทุกอย่างที่ต้องการ

??? ไชโย !!! ขอบคุณสำหรับการอ่าน!! ???