ตัวดำเนินการ !!: เมื่อใดและเหตุใดควรหลีกเลี่ยง
ทำความเข้าใจตัวดำเนินการยืนยันว่าไม่เป็น null ความเสี่ยง และทางเลือกที่ดีกว่า
ตัวดำเนินการ !!: เมื่อใดและเหตุใดควรหลีกเลี่ยง เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
!! คืออะไร
ตัวดำเนินการ ยืนยันว่าไม่เป็นค่าว่าง !! จะแปลงชนิดที่รับค่าว่างได้ให้เป็นชนิดที่ไม่เป็นค่าว่าง หากค่าดังกล่าวเป็นค่าว่างขณะรันโปรแกรม จะโยน NullPointerException
การใช้ !! เบื้องต้น
x!! จะคืนค่า x หากไม่เป็นค่าว่าง มิฉะนั้นจะโยน NPE
fun main() {
val name: String? = "Kotlin"
val len: Int = name!!.length // 6
println(len)
}!! จะโยนข้อผิดพลาดเมื่อเป็นค่าว่าง
หากค่าดังกล่าวเป็นค่าว่างจริง คุณจะได้รับข้อผิดพลาดเดียวกับที่ Kotlin พยายามป้องกัน
fun main() {
val name: String? = null
try {
println(name!!.length)
} catch (e: NullPointerException) {
println("NPE caught!")
}
}ทางเลือกที่ดีกว่า: การเรียกแบบปลอดภัย
แทนที่จะใช้ !! ควรเลือกใช้ ?. เพื่อจัดการกรณีต่าง ๆ อย่างเหมาะสมโดยไม่ทำให้โปรแกรมขัดข้อง
fun main() {
val name: String? = null
val len = name?.length
println(len) // null — no crash
}ทางเลือกที่ดีกว่า: ตัวดำเนินการ Elvis
จับคู่ ?. กับ ?: เพื่อกำหนดค่าทดแทนที่เหมาะสม
fun main() {
val name: String? = null
val len = name?.length ?: 0
println(len) // 0
}ทางเลือกที่ดีกว่า: การแปลงชนิดอัจฉริยะ
การตรวจสอบด้วย if (x != null) จะเปิดใช้การแปลงชนิดอัจฉริยะ จึงไม่จำเป็นต้องใช้ !!
fun main() {
val name: String? = "Alice"
if (name != null) {
println(name.length) // smart-cast to String
}
}ทางเลือกที่ดีกว่า: requireNotNull
หากค่าดังกล่าวต้องมีอยู่ requireNotNull(x) { "..." } จะโยน IllegalArgumentException ที่สื่อความหมายได้ชัดเจน
fun process(name: String?) {
val safe = requireNotNull(name) { "name is required" }
println("processing $safe")
}
fun main() {
process("Ada")
// process(null) // throws IllegalArgumentException: name is required
}ทางเลือกที่ดีกว่า: checkNotNull
checkNotNull(x) ทำงานในลักษณะเดียวกัน แต่จะโยน IllegalStateException ให้ใช้สำหรับตรวจสอบเงื่อนไขคงที่
class Service {
private var data: String? = null
fun load() { data = "loaded" }
fun read(): String = checkNotNull(data) { "load() must be called first" }
}
fun main() {
val s = Service()
s.load()
println(s.read())
}กรณีที่เหมาะสมสำหรับการใช้ !!
แม้จะพบไม่บ่อยแต่ก็ใช้ได้ในกรณีที่การไม่มีค่าว่างเป็นเงื่อนไขคงที่ซึ่งไม่สามารถพิสูจน์ได้ขณะคอมไพล์จริง ๆ เช่น หลังการเรียกผ่านการสะท้อน โปรดใส่ความคิดเห็นอธิบายเหตุผล
fun main() {
val list = listOf(1, 2, 3)
val firstEven: Int = list.find { it % 2 == 0 }!! // safe: we know list has an even
println(firstEven)
}การใช้ !! ต่อกัน — รูปแบบที่ควรหลีกเลี่ยงอย่างยิ่ง
การใช้ !! หลายรายการต่อกันเป็นสัญญาณว่าควรปรับปรุงโค้ดใหม่ ให้ปรับโครงสร้างโดยใช้การเรียกแบบปลอดภัยและประโยคตรวจสอบเบื้องต้น
class A(val b: B?)
class B(val c: C?)
class C(val name: String?)
fun main() {
val a: A? = A(B(C("ok")))
// BAD: val n = a!!.b!!.c!!.name!!
val n = a?.b?.c?.name ?: "unknown"
println(n)
}การปรับโครงสร้างเพื่อนำ !! ออก
แทนที่ !! ด้วยส่วนติดต่อที่ตรงไปตรงมามากกว่า เช่น ค่าที่ฟังก์ชันคืนซึ่งรับค่าว่างได้ การใช้ requireNotNull ตั้งแต่จุดเริ่มต้น หรือการคืนค่าออกจากฟังก์ชันแต่เนิ่น ๆ
fun firstUpper(s: String?): String? = s?.firstOrNull()?.uppercase()
fun main() {
println(firstUpper("alice")) // A
println(firstUpper("")) // null
println(firstUpper(null)) // null
}ตรวจสอบความเข้าใจ
จะเกิดอะไรขึ้นหากคุณใช้ !! กับค่าที่เป็นค่าว่างจริงขณะรันโปรแกรม
สรุปทบทวน
!! เป็นช่องทางหลีกเลี่ยงข้อจำกัดที่ทำลายความปลอดภัยจากค่าว่างของ Kotlin ควรเลือกใช้ ?. ?: การแปลงชนิดอัจฉริยะ requireNotNull หรือ checkNotNull และสงวน !! ไว้สำหรับเงื่อนไขคงที่ที่มีคำอธิบายกำกับและคอมไพเลอร์ไม่สามารถพิสูจน์ได้
เรียนรู้ Kotlin ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 51
- บทเรียน
- 203
คำถามที่พบบ่อย
บทเรียน “ตัวดำเนินการ !!: เมื่อใดและเหตุใดควรหลีกเลี่ยง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ตัวดำเนินการ !!: เมื่อใดและเหตุใดควรหลีกเลี่ยง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ตัวดำเนินการ !!: เมื่อใดและเหตุใดควรหลีกเลี่ยง”
ทำความเข้าใจตัวดำเนินการยืนยันว่าไม่เป็น null ความเสี่ยง และทางเลือกที่ดีกว่า คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ตัวดำเนินการ !!: เมื่อใดและเหตุใดควรหลีกเลี่ยง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม
ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ชนิด Nullable และตัวปรับแต่ง ?
- Safe Call ?. และ Elvis ?: ในโค้ดจริง
- let, also และ run กับตัวรับ Nullable
- ตัวดำเนินการ !!: เมื่อใดและเหตุใดควรหลีกเลี่ยง