การแปลงชนิดแบบบังคับด้วย as! และความเสี่ยง
ใช้ as! เฉพาะเมื่อมั่นใจว่าการแปลงชนิดจะสำเร็จ
การแปลงชนิดแบบบังคับด้วย as! และความเสี่ยง เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
การแคสต์แบบบังคับ
ตัวดำเนินการ แคสต์แบบบังคับ as! จะแคสต์ลงและแกะค่าในขั้นตอนเดียว ทำให้ได้ชนิดที่ไม่ใช่ค่าทางเลือกโดยตรง แต่จะ ทำให้โปรแกรมหยุดทำงาน หากการแคสต์ล้มเหลว
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let dog = a as! Dog
print(dog.bark())ไม่มีการห่อหุ้มเป็นค่าทางเลือก
ต่างจาก as? ผลลัพธ์ของ as! เป็นชนิดปกติ ไม่ใช่ค่าทางเลือก จึงไม่มีสิ่งใดให้แกะค่า
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let dog: Dog = a as! Dog
print(type(of: dog))ความเสี่ยงของ as!
หากอินสแตนซ์ไม่ใช่ชนิดเป้าหมายจริง as! จะทำให้เกิดข้อผิดพลาดร้ายแรงขณะทำงานและหยุดโปรแกรม ไม่มีวิธีกู้คืนจากกรณีนี้
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
// let cat = a as! Cat // would crash at runtime
print("Only force-cast when certain")เมื่อการแคสต์แบบบังคับปลอดภัย
ใช้ as! เฉพาะเมื่อคุณมั่นใจอย่างแน่นอนในชนิดข้อมูล เช่น ใช้ทันทีหลังตรวจสอบด้วย is
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
if a is Dog {
let dog = a as! Dog
print(dog.bark())
}การแคสต์แบบบังคับหลังการรับประกันชนิดข้อมูล
หากตรรกะของโค้ดรับประกันชนิดข้อมูลได้ การแคสต์แบบบังคับจะช่วยบันทึกความแน่ใจนั้นไว้อย่างชัดเจน แต่หากไม่แน่ใจ ควรเลือกใช้ as?
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
func barkIfDog(_ a: Animal) {
guard a is Dog else { return }
let dog = a as! Dog
print(dog.bark())
}
barkIfDog(Dog(name: "Rex"))การเปรียบเทียบ as? กับ as!
as? ปลอดภัยและคืนค่าทางเลือก ส่วน as! เป็นการบังคับและทำให้โปรแกรมหยุดทำงานเมื่อล้มเหลว ให้เลือกใช้ตามระดับความแน่ใจของคุณ
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let safe = a as? Dog
let forced = a as! Dog
print(safe?.bark() ?? "nil")
print(forced.bark())การแคสต์คอลเลกชันแบบบังคับ
การแคสต์แบบบังคับใช้กับคอลเลกชันทั้งชุดได้เช่นกัน เช่น array as! [Dog] แต่ยังมีความเสี่ยงที่สมาชิกทุกตัวจะทำให้โปรแกรมหยุดทำงานเช่นเดิม
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let animals: [Animal] = [Dog(name: "Rex"), Dog(name: "Buddy")]
let dogs = animals as! [Dog]
for d in dogs { print(d.bark()) }รูปแบบที่อันตราย
การแคสต์แบบบังคับกับอาร์เรย์ที่มีสมาชิกผิดชนิดจะทำให้โปรแกรมหยุดทำงาน นี่คือเหตุผลที่คอลเลกชันหลายชนิดควรใช้ as? กับสมาชิกแต่ละตัว
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let animals: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
// let dogs = animals as! [Dog] // would crash on the Cat
for a in animals {
if let d = a as? Dog { print(d.bark()) }
}การแกะค่าแบบบังคับเทียบกับการแคสต์แบบบังคับ
! ใน as! มีแนวคิดคล้ายกับการแกะค่าทางเลือกแบบบังคับ คือสะดวกแต่เป็นอันตรายหากข้อสมมติไม่ถูกต้อง
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let viaOptional = (a as? Dog)!
let viaForce = a as! Dog
print(viaOptional.name, viaForce.name)แนวทางปฏิบัติที่ดี
ให้ใช้ as? เป็นค่าเริ่มต้น เก็บ as! ไว้สำหรับกรณีที่ความล้มเหลวหมายถึงข้อผิดพลาดของโปรแกรมเมอร์ ซึ่งคุณต้องการให้แสดงทันทีระหว่างการพัฒนา
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
func process(_ a: Animal) -> String {
if let d = a as? Dog { return d.bark() }
return "not a dog"
}
print(process(Dog(name: "Rex")))
print(process(Cat(name: "Mia")))ตัวอย่างสรุปการแคสต์แบบบังคับ
เมื่อมีการตรวจสอบชนิดข้อมูลแล้ว as! จะอ่านเข้าใจได้ง่าย แต่เมื่อไม่แน่ใจ การแคสต์แบบมีเงื่อนไขที่ปลอดภัยคือเครื่องมือที่เหมาะสม
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let known: Animal = Dog(name: "Rex")
if known is Dog {
print((known as! Dog).bark())
}ตรวจสอบอย่างรวดเร็ว
จงพิจารณาอันตรายของการแคสต์แบบบังคับ
สรุป: การแคสต์แบบบังคับและความเสี่ยง
คุณได้เรียนรู้ว่า as! จะแคสต์ลงและแกะค่าเป็นชนิดที่ไม่ใช่ค่าทางเลือก แต่ทำให้โปรแกรมหยุดทำงานเมื่อล้มเหลว ควรใช้เฉพาะเมื่อมั่นใจในชนิดข้อมูลเท่านั้น โดยมักใช้หลังการตรวจสอบด้วย is และ as? ยังคงเป็นค่าเริ่มต้นที่ปลอดภัยกว่า
class Animal {
let name: String
init(name: String) { self.name = name }
}
class Dog: Animal {
func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
if a is Dog { print((a as! Dog).bark()) } else { print("safe skip") }คำถามที่พบบ่อย
บทเรียน “การแปลงชนิดแบบบังคับด้วย as! และความเสี่ยง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การแปลงชนิดแบบบังคับด้วย as! และความเสี่ยง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การแปลงชนิดแบบบังคับด้วย as! และความเสี่ยง”
ใช้ as! เฉพาะเมื่อมั่นใจว่าการแปลงชนิดจะสำเร็จ คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การแปลงชนิดแบบบังคับด้วย as! และความเสี่ยง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐานการแปลงชนิดขึ้นและลง
- การแปลงชนิดแบบมีเงื่อนไขด้วย as?
- การแปลงชนิดแบบบังคับด้วย as! และความเสี่ยง
- การตรวจสอบชนิดด้วย is