Optional / Nullable — กลไกของภาษา Swift และ Kotlin สำหรับการทำงานอย่างปลอดภัยเมื่อไม่มีค่า Optional ใน Swift และชนิด nullable ใน Kotlin แก้ปัญหาเดียวกัน — null reference — แต่ด้วยวิธีการทางไวยากรณ์และความหมายที่แตกต่างกัน ตามข้อมูลจาก Swift.org, 2026 ชนิดออปชันแนลช่วยกำจัดข้อผิดพลาดทั้งคลาสที่เกี่ยวข้องกับ nil โดยย้ายการตรวจสอบ null ไปยังขั้นตอนการคอมไพล์
ประเด็นสำคัญ
Optional ใน Swift และ nullable ใน Kotlin เป็นเครื่องมือทางภาษาที่ทำให้ null เป็นส่วนหนึ่งของระบบชนิดอย่างชัดเจน ใน Swift Optional คือ enum: Optional.none (nil) และ Optional.some(Wrapped) ใน Kotlin nullable ระบุด้วยคำต่อท้าย ? ในชนิด: String? สามารถเป็นสตริงหรือ null ได้
ทั้งสองแนวทางแก้ไขปัญหาพื้นฐานที่ Tony Hoare เรียกว่า “ข้อผิดพลาดมูลค่าพันล้านดอลลาร์” — null reference ก่อนที่ชนิดออปชันแนลจะเกิดขึ้น การอ้างอิงใดๆ ก็สามารถเป็น null ได้และการตรวจสอบก็ขึ้นอยู่กับนักพัฒนา Swift และ Kotlin ย้ายการตรวจสอบนี้ไปยัง ขั้นตอนการคอมไพล์: โค้ดที่ไม่สนใจ null จะไม่สามารถคอมไพล์ได้
แม้จะมีเป้าหมายร่วมกัน Swift และ Kotlin implements null-safety แตกต่างกัน Swift ใช้ชนิดเชิงพีชคณิต Optional พร้อมการจับคู่รูปแบบเต็มรูปแบบ Kotlin ฝัง nullable ในระบบชนิดในระดับคอมไพเลอร์โดยไม่สร้างชนิด wrapper แยกต่างหาก
ในอดีต null reference ปรากฏในปี 1965 ในภาษา ALGOL W เพื่อแสดงถึงการไม่มีค่า ตลอดหกทศวรรษ null กลายเป็นแหล่งที่มาของความล้มเหลวนับไม่ถ้วน — ตามการวิจัยของ Tony Hoare ข้อผิดพลาด 30 ถึง 50 เปอร์เซ็นต์ในโค้ดการผลิตเกี่ยวข้องกับ NullPointerException Swift พร้อม Optional และ Kotlin พร้อมชนิด nullable กลายเป็นภาษากระแสหลักภาษาแรกที่แก้ไขปัญหานี้ในระดับระบบชนิด ทำให้ null เป็นส่วนหนึ่งของสัญญาฟังก์ชันอย่างชัดเจน
ใน Swift Optional เป็นชนิดเต็มรูปแบบที่ประกาศเป็น enum Optional<Wrapped> น้ำตาลทางไวยากรณ์ ? แทนที่สัญกรณ์เต็ม: Int? เทียบเท่ากับ Optional<Int> การทำงานกับ Optional รวมถึงหลายวิธีในการแยกค่า
if let — การแยกแบบมีเงื่อนไข: ถ้า Optional มีค่า ค่านั้นจะถูกผูกกับค่าคงที่ภายในบล็อก guard let — การออกจากฟังก์ชันก่อนกำหนดถ้า Optional เป็น nil guard let ทำให้โค้ดเรียบ หลีกเลี่ยง if-let ที่ซ้อนกัน
การเชื่อมโยงออปชันแนล (การเข้าถึงอย่างปลอดภัยตามลำดับ) ผ่าน ? อนุญาตให้เรียกเมธอดหรือพรอพเพอร์ตี้บน Optional โดยไม่ต้องแกะห่ออย่างชัดเจน ถ้าลิงก์ใดๆ ในห่วงโซ่เป็น nil ทั้งห่วงโซ่จะคืนค่า nil ซึ่งช่วยลดโค้ดเมื่อทำงานกับข้อมูลแบบลำดับชั้น
?? (nil-coalescing) — ตัวดำเนินการที่คืนค่า Optional ถ้าไม่ใช่ nil มิฉะนั้นจะคืนค่าเริ่มต้น เป็นทางเลือกที่กระชับสำหรับ if-let ในการให้ค่าสำรอง
var name: String? = "Alice"
// การผูก If-let
if let unwrapped = name {
print("สวัสดี, \(unwrapped)")
}
// การเชื่อมโยงออปชันแนล
let count = name?.count
// Nil-coalescing
let display = name ?? "แขก"
// Map บน Optional
let greeting = name.map { "Hello, \($0)" }
ใน Kotlin nullable เป็นส่วนหนึ่งของระบบชนิด ไม่ใช่ชนิด wrapper แยกต่างหาก ชนิด String? สามารถมีค่า null ได้ ในขณะที่ String (ไม่มีเครื่องหมายคำถาม) ไม่สามารถมีได้ คอมไพเลอร์ติดตาม nullable ผ่าน smart cast และคำอธิบายประกอบ
?. — ตัวดำเนินการเรียกอย่างปลอดภัย ถ้าวัตถุไม่ใช่ null เมธอดหรือพรอพเพอร์ตี้จะถูกเรียก ถ้าเป็น null — คืนค่า null โดยไม่เรียก ซึ่งคล้ายกับการเชื่อมโยงออปชันแนลใน Swift แต่สั้นกว่าในเชิงไวยากรณ์
?: — เวอร์ชัน Kotlin ของ nil-coalescing ถ้านิพจน์ทางซ้ายไม่ใช่ null มันจะถูกคืน มิฉะนั้น — ค่าทางขวา ตัวดำเนินการ Elvis มักรวมกับการออกก่อนกำหนดผ่าน return หรือ throw
Smart cast — คอมไพเลอร์ Kotlin แปลง nullable เป็น non-null โดยอัตโนมัติหลังจากตรวจสอบ null ใน if หรือ when !! — การบังคับแกะห่อที่โยน NullPointerException เมื่อเป็น null ใช้ !! เฉพาะเมื่อ null เป็นบั๊ก
val name: String? = "Alice"
// การเรียกอย่างปลอดภัย
val length = name?.length
// ตัวดำเนินการ Elvis
val display = name ?: "แขก"
// Smart cast หลังการตรวจสอบ
if (name != null) {
println("ความยาว: ${name.length}")
}
// Let กับแลมบ์ดา
name?.let { println("สวัสดี, $it") }
// Force unwrap — เฉพาะเมื่อแน่ใจ
val forced = name!!
แม้ว่า Swift และ Kotlin จะแก้ปัญหาเดียวกัน แนวทางของพวกเขาต่อ null-safety แตกต่างกันโดยพื้นฐาน การเข้าใจความแตกต่างเหล่านี้สำคัญสำหรับนักพัฒนาที่ทำงานกับทั้งสองแพลตฟอร์ม
Swift ใช้ enum Optional — ชนิดเชิงพีชคณิตมาตรฐาน Kotlin ฝัง nullable ในระดับ ระบบชนิดของคอมไพเลอร์ โดยไม่สร้างวัตถุ wrapper สิ่งนี้ส่งผลต่อประสิทธิภาพ: Optional ใน Swift เป็นวัตถุบนฮีป ในขณะที่ nullable ใน Kotlin เป็นการตรวจสอบ null โดยไม่มีการจัดสรรหน่วยความจำ
ไวยากรณ์ของ Kotlin สั้นกว่าด้วยตัวดำเนินการในตัว ?., ?:, !! Swift ต้องการไวยากรณ์ที่ชัดเจนกว่า: if let, guard let, map บน Optional อย่างไรก็ตาม Swift มี การจับคู่รูปแบบ ผ่าน switch ซึ่ง Kotlin ไม่รองรับโดยตรงสำหรับ nullable
| สถานการณ์ | Swift | Kotlin |
|---|---|---|
| การประกาศ | var name: String? | val name: String? |
| การเรียกอย่างปลอดภัย | name?.count | name?.length |
| ค่าเริ่มต้น | name ?? “แขก” | name ?: “แขก” |
| การแยกแบบมีเงื่อนไข | if let x = name | name?.let { x -> } |
| Force unwrap | name! | name!! |
ในการพัฒนาแอปพลิเคชันมือถือ ได้มีรูปแบบมาตรฐานสำหรับการทำงานกับชนิดออปชันแนลที่เกิดขึ้น ซึ่งลดโค้ดเทมเพลตและเพิ่มความปลอดภัย
Swift และ Kotlin รองรับ map และ flatMap สำหรับ Optional และ nullable ถ้ามีค่าอยู่ — จะใช้การแปลง ถ้าเป็น null — คืนค่า null ซึ่งช่วยขจัดการตรวจสอบ if-let ที่ซ้อนกัน
แทนที่ if-let + else ให้ใช้ ?: หรือ ?? พร้อมค่าเริ่มต้น ทำให้โค้ดเป็นเชิงประกาศ: “ใช้ X ถ้ามี มิฉะนั้นใช้ Y” แทนการตรวจสอบเชิงกระบวน
ใน Jetpack Compose และ SwiftUI ชนิดออปชันแนลควบคุมการแสดงผล: ถ้าสถานะเป็น null — ซ่อนคอมโพเนนต์ มิฉะนั้นแสดง ซึ่งเป็นไปตามหลักการ single source of truth
data class UserState(
val name: String?,
val email: String?
)
// Smart cast ใน when ด้วยตัวแปรที่แตกต่างกัน
fun greeting(state: UserState): String = when {
state.name != null && state.email != null ->
"${state.name} (${state.email})"
state.name != null -> state.name
else -> "แขก"
}
// Compose: การแสดงตามการมีอยู่
@Composable
fun UserProfile(name: String?) {
name?.let {
Text(text = it)
} ?: Text(text = "ไม่มีข้อมูล")
}
สำหรับการย้ายโค้ด Java ที่มีอยู่ไปยัง Kotlin แนะนำให้ใช้คำอธิบายประกอบ @Nullable และ @NonNull จากแพ็คเกจ androidx.annotation คอมไพเลอร์ Kotlin เคารพคำอธิบายประกอบเหล่านี้ระหว่างการทำงานร่วมกับ Java ทำให้ชนิดที่เกี่ยวข้องเป็น nullable หรือ non-null โดยอัตโนมัติ การย้ายแบบค่อยเป็นค่อยไปด้วยคำอธิบายประกอบที่ชัดเจนปลอดภัยกว่าการเปิดใช้ null-safety ทั่วโลกในโปรเจกต์
Null-safety ลดจำนวนข้อผิดพลาด แต่ไม่ได้กำจัดทั้งหมด นักพัฒนามักทำผิดพลาดลักษณะเฉพาะเมื่อทำงานกับชนิดออปชันแนล
คำถามที่พบบ่อย
Swift Optional เป็น enum ที่มีเคส some และ none เป็นวัตถุบนฮีป Kotlin nullable เป็นคำอธิบายประกอบในระบบชนิดที่ตรวจสอบโดยคอมไพเลอร์โดยไม่สร้าง wrapper Kotlin กระชับกว่าในเชิงไวยากรณ์ Swift มีประสิทธิภาพมากกว่าในการจับคู่รูปแบบ
Java ไม่มี null-safety ในตัว Optional (Java 8+) คล้ายกับ Swift Optional แต่เป็น wrapper ที่มีค่าใช้จ่ายเพิ่มเติม คำอธิบายประกอบ @Nullable และ @NonNull ช่วยเครื่องมือวิเคราะห์แบบสแตติกแต่ไม่รับประกันความปลอดภัย
?.let สะดวกสำหรับการเชื่อมโยงการดำเนินการ: ใช้การแปลง บันทึกในฐานข้อมูล อัปเดต UI — ทั้งหมดในบล็อกเดียว if พร้อมการตรวจสอบ null ดีกว่าสำหรับเงื่อนไขที่ซับซ้อนด้วยตัวแปร nullable หลายตัว
Swift Optional เป็น enum ที่มีการจัดเก็บทางอ้อมสำหรับชนิดขนาดใหญ่ ซึ่งอาจทำให้เกิดการจัดสรรหน่วยความจำ Kotlin nullable เป็นการตรวจสอบ null โดยไม่มีค่าใช้จ่ายเพิ่มเติม สำหรับเส้นทางร้อน (recycler view, อนิเมชัน) Kotlin มีประสิทธิภาพมากกว่า
ใช้ nullable เฉพาะเมื่อฟิลด์อาจไม่มีอยู่จริง: ข้อมูลโปรไฟล์ที่เป็นตัวเลือก การตั้งค่าที่ไม่บังคับ ถ้าฟิลด์ถูกกรอกเสมอ ให้ใช้ non-null พร้อมค่าเริ่มต้นผ่านตัวดำเนินการ Elvis เมื่อสร้าง
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม