ชนิดดำรงอยู่ด้วย any และการลบชนิด
ใช้ any Protocol ทำความเข้าใจต้นทุนด้านประสิทธิภาพ และทราบว่าเมื่อใดควรเลือกชนิดทั่วไป
ชนิดดำรงอยู่ด้วย any และการลบชนิด เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
ประเภทอัตถิภาวะคืออะไร
ประเภทอัตถิภาวะจะบรรจุค่าใดก็ได้ที่สอดคล้องกับโพรโทคอลไว้เบื้องหลังอินเทอร์เฟซแบบเดียวกัน โดยแก้ไขการทำงานขณะรันไทม์
protocol Drawable { func draw() }
struct Line: Drawable { func draw() { print("Line") } }
let d: any Drawable = Line()
d.draw()คีย์เวิร์ด any
Swift 5.7 กำหนดให้ใช้คีย์เวิร์ด any ก่อนชื่อโพรโทคอลที่ใช้เป็นประเภทอัตถิภาวะ เพื่อให้การบรรจุค่ามีความชัดเจน
func render(_ shape: any Drawable) {
shape.draw()
}
render(Line())ต้นทุนของประเภทอัตถิภาวะ
ประเภทอัตถิภาวะใช้การจัดสรรหน่วยความจำบนฮีพและการเรียกแบบไดนามิก ซึ่งอาจช้ากว่า generic ที่ใช้การเรียกแบบคงที่
// Existential – dynamic dispatch, potential heap alloc
var shapes: [any Drawable] = [Line(), Line()]
// Generic – static dispatch, no boxing
func drawGeneric<T: Drawable>(_ s: T) { s.draw() }ปัญหาของ PAT และประเภทอัตถิภาวะ
โพรโทคอลที่มีชนิดที่เกี่ยวข้องไม่สามารถใช้เป็นชนิดอัตถิภาวะโดยตรงได้ หากไม่มีการลบชนิดข้อมูล
protocol Container { associatedtype Item }
// var c: any Container // Swift 5.7 allows with "any" but loses Item infoรูปแบบการลบชนิดข้อมูล
ตัวห่อหุ้มที่ลบชนิดข้อมูลจะห่อชนิดข้อมูลรูปธรรมไว้ภายในโครงสร้าง โดยซ่อนชนิดข้อมูลรูปธรรมดังกล่าว
struct AnyDrawable: Drawable {
private let _draw: () -> Void
init<D: Drawable>(_ d: D) { _draw = d.draw }
func draw() { _draw() }
}AnySequence และ AnyPublisher
ไลบรารีมาตรฐานของ Swift และ Combine มีตัวห่อหุ้มที่ลบชนิดข้อมูล เช่น AnySequence และ AnyPublisher
import Combine
let subject = PassthroughSubject<Int, Never>()
let pub: AnyPublisher<Int, Never> = subject.eraseToAnyPublisher()eraseToAnyPublisher()
eraseToAnyPublisher() ซ่อนสายผู้เผยแพร่ข้อมูลรูปธรรม ทำให้โค้ดที่เรียกใช้พึ่งพาเฉพาะ AnyPublisher
func fetch() -> AnyPublisher<String, Error> {
URLSession.shared.dataTaskPublisher(for: URL(string: "https://example.com")!)
.map { String(data: $0.data, encoding: .utf8) ?? "" }
.eraseToAnyPublisher()
}เมื่อใดจึงควรใช้ชนิดอัตถิภาวะ
ใช้ชนิดอัตถิภาวะกับคอลเลกชันที่มีสมาชิกต่างชนิดกัน หรือเมื่อไม่ทราบชนิดข้อมูลที่แน่นอนขณะคอมไพล์
var widgets: [any Drawable] = [] // mixed concrete types OKเลือกใช้เจเนอริกแทนชนิดอัตถิภาวะ
เมื่อทำได้ ให้แทนที่ชนิดอัตถิภาวะด้วยเจเนอริก เพื่อให้ได้การเรียกใช้แบบสแตติกและประสิทธิภาพที่ดีขึ้น
// Prefer this:
func draw<T: Drawable>(_ item: T) { item.draw() }
// Over this:
func draw(_ item: any Drawable) { item.draw() }การเปิดชนิดอัตถิภาวะ
Swift 5.7 ขึ้นไปสามารถเปิดชนิดอัตถิภาวะเมื่อเรียกใช้ฟังก์ชันเจเนอริก โดยแยกชนิดข้อมูลพื้นฐานออกมาโดยอัตโนมัติ
func drawGeneric<T: Drawable>(_ d: T) { d.draw() }
let d: any Drawable = Line()
drawGeneric(d) // compiler opens the existential automaticallyการลบชนิดข้อมูลเทียบกับชนิดข้อมูลทึบ
การลบชนิดข้อมูลจะซ่อนชนิดข้อมูลเพื่อให้ใช้งานกับข้อมูลต่างชนิดกันได้ ส่วนชนิดข้อมูลทึบจะคงเอกลักษณ์ของชนิดข้อมูลไว้สำหรับชนิดผลลัพธ์เดียวที่สอดคล้องกัน
let erased: any Drawable = Line() // runtime type unknown
let opaque: some Drawable = Line() // compile-time fixed typeตรวจสอบความเข้าใจ
ต้นทุนด้านประสิทธิภาพหลักของชนิดอัตถิภาวะคืออะไร
ทบทวนบทเรียน
ชนิดอัตถิภาวะ (any Protocol) ทำให้เกิดพหุรูปแบบขณะทำงาน โดยมีต้นทุนเป็นการเรียกใช้แบบไดนามิก การลบชนิดข้อมูลจะห่อชนิดข้อมูลรูปธรรมไว้เบื้องหลังอินเทอร์เฟซที่เสถียร ควรเลือกใช้เจเนอริกเพื่อประสิทธิภาพ และใช้ชนิดอัตถิภาวะกับคอลเลกชันที่มีสมาชิกต่างชนิดกัน
คำถามที่พบบ่อย
บทเรียน “ชนิดดำรงอยู่ด้วย any และการลบชนิด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ชนิดดำรงอยู่ด้วย any และการลบชนิด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ชนิดดำรงอยู่ด้วย any และการลบชนิด”
ใช้ any Protocol ทำความเข้าใจต้นทุนด้านประสิทธิภาพ และทราบว่าเมื่อใดควรเลือกชนิดทั่วไป คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ชนิดดำรงอยู่ด้วย any และการลบชนิด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ข้อจำกัดของชนิดทั่วไปและส่วนคำสั่ง where
- ชนิดทึบแสงด้วยคีย์เวิร์ด some
- ชนิดดำรงอยู่ด้วย any และการลบชนิด
- ชนิดที่เชื่อมโยงหลักและการโยนข้อผิดพลาดที่มีชนิด