Optional / Nullable — แนวคิดสำคัญและการทำงานกับชนิด nullable

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-05-26 เวลาอ่าน: 8 นาที

Optional / Nullable — กลไกของภาษา Swift และ Kotlin สำหรับการทำงานอย่างปลอดภัยเมื่อไม่มีค่า Optional ใน Swift และชนิด nullable ใน Kotlin แก้ปัญหาเดียวกัน — null reference — แต่ด้วยวิธีการทางไวยากรณ์และความหมายที่แตกต่างกัน ตามข้อมูลจาก Swift.org, 2026 ชนิดออปชันแนลช่วยกำจัดข้อผิดพลาดทั้งคลาสที่เกี่ยวข้องกับ nil โดยย้ายการตรวจสอบ null ไปยังขั้นตอนการคอมไพล์

ประเด็นสำคัญ

  • Optional — ชนิดของ Swift ที่แสดงเป็น enum ด้วยสองเคส: some(Value) และ none
  • Nullable — ใน Kotlin ระบุด้วยเครื่องหมายคำถามหลังชนิด (String?) และการเรียกอย่างปลอดภัยผ่าน ?.
  • ความปลอดภัยของชนิด — กลไกทั้งสองรับประกันว่าค่า null ถูกจัดการอย่างชัดเจนในขั้นตอนการคอมไพล์
  • การแกะห่อ — Swift ใช้ if let, guard let และ force unwrap (!) Kotlin ใช้ ?., !! และตัวดำเนินการ Elvis ?:
  • การทำงานร่วมกัน — Kotlin และ Swift โต้ตอบกับโค้ดเบส nullable ผ่านคำอธิบายประกอบและชนิดพิเศษ (Implicitly Unwrapped Optional)

Optional และ Nullable คืออะไร?

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 เป็นส่วนหนึ่งของสัญญาฟังก์ชันอย่างชัดเจน

Optional ใน Swift: ไวยากรณ์และการทำงานกับชนิดออปชันแนล

ใน Swift Optional เป็นชนิดเต็มรูปแบบที่ประกาศเป็น enum Optional<Wrapped> น้ำตาลทางไวยากรณ์ ? แทนที่สัญกรณ์เต็ม: Int? เทียบเท่ากับ Optional<Int> การทำงานกับ Optional รวมถึงหลายวิธีในการแยกค่า

การผูก if-let และ guard-let

if let — การแยกแบบมีเงื่อนไข: ถ้า Optional มีค่า ค่านั้นจะถูกผูกกับค่าคงที่ภายในบล็อก guard let — การออกจากฟังก์ชันก่อนกำหนดถ้า Optional เป็น nil guard let ทำให้โค้ดเรียบ หลีกเลี่ยง if-let ที่ซ้อนกัน

การเชื่อมโยงออปชันแนล

การเชื่อมโยงออปชันแนล (การเข้าถึงอย่างปลอดภัยตามลำดับ) ผ่าน ? อนุญาตให้เรียกเมธอดหรือพรอพเพอร์ตี้บน Optional โดยไม่ต้องแกะห่ออย่างชัดเจน ถ้าลิงก์ใดๆ ในห่วงโซ่เป็น nil ทั้งห่วงโซ่จะคืนค่า nil ซึ่งช่วยลดโค้ดเมื่อทำงานกับข้อมูลแบบลำดับชั้น

ตัวดำเนินการ nil-coalescing

?? (nil-coalescing) — ตัวดำเนินการที่คืนค่า Optional ถ้าไม่ใช่ nil มิฉะนั้นจะคืนค่าเริ่มต้น เป็นทางเลือกที่กระชับสำหรับ if-let ในการให้ค่าสำรอง

swift
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)" }

Nullable ใน Kotlin: การเรียกอย่างปลอดภัยและตัวดำเนินการ Elvis

ใน Kotlin nullable เป็นส่วนหนึ่งของระบบชนิด ไม่ใช่ชนิด wrapper แยกต่างหาก ชนิด String? สามารถมีค่า null ได้ ในขณะที่ String (ไม่มีเครื่องหมายคำถาม) ไม่สามารถมีได้ คอมไพเลอร์ติดตาม nullable ผ่าน smart cast และคำอธิบายประกอบ

การเรียกอย่างปลอดภัย ?.

?. — ตัวดำเนินการเรียกอย่างปลอดภัย ถ้าวัตถุไม่ใช่ null เมธอดหรือพรอพเพอร์ตี้จะถูกเรียก ถ้าเป็น null — คืนค่า null โดยไม่เรียก ซึ่งคล้ายกับการเชื่อมโยงออปชันแนลใน Swift แต่สั้นกว่าในเชิงไวยากรณ์

ตัวดำเนินการ Elvis ?:

?: — เวอร์ชัน Kotlin ของ nil-coalescing ถ้านิพจน์ทางซ้ายไม่ใช่ null มันจะถูกคืน มิฉะนั้น — ค่าทางขวา ตัวดำเนินการ Elvis มักรวมกับการออกก่อนกำหนดผ่าน return หรือ throw

Smart cast และตัวดำเนินการ !!

Smart cast — คอมไพเลอร์ Kotlin แปลง nullable เป็น non-null โดยอัตโนมัติหลังจากตรวจสอบ null ใน if หรือ when !! — การบังคับแกะห่อที่โยน NullPointerException เมื่อเป็น null ใช้ !! เฉพาะเมื่อ null เป็นบั๊ก

kotlin
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!!

Optional กับ Nullable: ความแตกต่างหลักของแนวทาง

แม้ว่า 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

สถานการณ์SwiftKotlin
การประกาศvar name: String?val name: String?
การเรียกอย่างปลอดภัยname?.countname?.length
ค่าเริ่มต้นname ?? “แขก”name ?: “แขก”
การแยกแบบมีเงื่อนไขif let x = namename?.let { x -> }
Force unwrapname!name!!

รูปแบบ null-safety ในการพัฒนาแอปพลิเคชันมือถือ

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

Map และ flatMap บน Optional

Swift และ Kotlin รองรับ map และ flatMap สำหรับ Optional และ nullable ถ้ามีค่าอยู่ — จะใช้การแปลง ถ้าเป็น null — คืนค่า null ซึ่งช่วยขจัดการตรวจสอบ if-let ที่ซ้อนกัน

ค่าเริ่มต้นผ่าน Elvis

แทนที่ if-let + else ให้ใช้ ?: หรือ ?? พร้อมค่าเริ่มต้น ทำให้โค้ดเป็นเชิงประกาศ: “ใช้ X ถ้ามี มิฉะนั้นใช้ Y” แทนการตรวจสอบเชิงกระบวน

Nullable ใน Compose และ SwiftUI

ใน Jetpack Compose และ SwiftUI ชนิดออปชันแนลควบคุมการแสดงผล: ถ้าสถานะเป็น null — ซ่อนคอมโพเนนต์ มิฉะนั้นแสดง ซึ่งเป็นไปตามหลักการ single source of truth

kotlin
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 ทั่วโลกในโปรเจกต์

ข้อผิดพลาดทั่วไปเมื่อทำงานกับ Optional และ Nullable

Null-safety ลดจำนวนข้อผิดพลาด แต่ไม่ได้กำจัดทั้งหมด นักพัฒนามักทำผิดพลาดลักษณะเฉพาะเมื่อทำงานกับชนิดออปชันแนล

  • Force unwrap โดยไม่มีการรับประกัน — name! หรือ name!! โดยไม่แน่ใจว่าค่าไม่ใช่ nil ทำให้เกิดการล่มในการผลิต ตรวจสอบ null ก่อน force unwrap
  • if-let ที่มากเกินไป — if-let ที่ซ้อนกันสำหรับสาม Optional ขึ้นไปสร้างพีระมิดแห่งความหายนะ ใช้ guard let หรือ flatMap
  • ละเลย nil-coalescing — การตรวจสอบอย่างชัดเจนผ่าน if-let พร้อมบล็อก else สามารถแทนที่ด้วย ?? หรือ ?: ซึ่งช่วยลดโค้ดและปรับปรุงความสามารถในการอ่าน
  • Nullable ใน API สาธารณะ — ถ้าฟังก์ชันยอมรับ nullable ทุกการเรียกต้องมีการตรวจสอบ ควรใช้ non-null พร้อมค่าเริ่มต้นหรือการโอเวอร์โหลด

คำถามที่พบบ่อย

Kotlin Nullable แตกต่างจาก Swift Optional อย่างไร?

Swift Optional เป็น enum ที่มีเคส some และ none เป็นวัตถุบนฮีป Kotlin nullable เป็นคำอธิบายประกอบในระบบชนิดที่ตรวจสอบโดยคอมไพเลอร์โดยไม่สร้าง wrapper Kotlin กระชับกว่าในเชิงไวยากรณ์ Swift มีประสิทธิภาพมากกว่าในการจับคู่รูปแบบ

Java มี null-safety หรือไม่?

Java ไม่มี null-safety ในตัว Optional (Java 8+) คล้ายกับ Swift Optional แต่เป็น wrapper ที่มีค่าใช้จ่ายเพิ่มเติม คำอธิบายประกอบ @Nullable และ @NonNull ช่วยเครื่องมือวิเคราะห์แบบสแตติกแต่ไม่รับประกันความปลอดภัย

เมื่อใดควรใช้ ?.let ใน Kotlin แทน if-let?

?.let สะดวกสำหรับการเชื่อมโยงการดำเนินการ: ใช้การแปลง บันทึกในฐานข้อมูล อัปเดต UI — ทั้งหมดในบล็อกเดียว if พร้อมการตรวจสอบ null ดีกว่าสำหรับเงื่อนไขที่ซับซ้อนด้วยตัวแปร nullable หลายตัว

Optional ส่งผลต่อประสิทธิภาพอย่างไร?

Swift Optional เป็น enum ที่มีการจัดเก็บทางอ้อมสำหรับชนิดขนาดใหญ่ ซึ่งอาจทำให้เกิดการจัดสรรหน่วยความจำ Kotlin nullable เป็นการตรวจสอบ null โดยไม่มีค่าใช้จ่ายเพิ่มเติม สำหรับเส้นทางร้อน (recycler view, อนิเมชัน) Kotlin มีประสิทธิภาพมากกว่า

ควรใช้ nullable สำหรับฟิลด์ของ data class หรือไม่?

ใช้ nullable เฉพาะเมื่อฟิลด์อาจไม่มีอยู่จริง: ข้อมูลโปรไฟล์ที่เป็นตัวเลือก การตั้งค่าที่ไม่บังคับ ถ้าฟิลด์ถูกกรอกเสมอ ให้ใช้ non-null พร้อมค่าเริ่มต้นผ่านตัวดำเนินการ Elvis เมื่อสร้าง

สรุป

  • Optional (Swift) และ Nullable (Kotlin) เป็นกลไกทางภาษาที่ย้ายการจัดการ null ไปยังขั้นตอนการคอมไพล์และป้องกัน NPE
  • Swift Optional เป็น enum ที่มีสองเคส ให้การจับคู่รูปแบบและ map/flatMap Kotlin nullable เป็น ส่วนหนึ่งของระบบชนิด พร้อมตัวดำเนินการกระทัดรัด ?., ?:, !!
  • การเชื่อมโยงออปชันแนล (Swift ?.) และ การเรียกอย่างปลอดภัย (Kotlin ?.) อนุญาตให้ทำงานกับข้อมูลแบบลำดับชั้นโดยไม่ต้องตรวจสอบซ้อนกัน
  • Nil-coalescing (??) และ ตัวดำเนินการ Elvis (?:) ให้ค่าเริ่มต้นโดยไม่ต้องมีสาขา if-else ที่ชัดเจน
  • Smart cast ใน Kotlin แปลง nullable เป็น non-null โดยอัตโนมัติหลังการตรวจสอบ ลดจำนวนการแปลงที่ชัดเจน
  • หลีกเลี่ยง force unwrap (! / !!) ในการผลิต if-let ที่มากเกินไป และชนิด nullable ใน API สาธารณะโดยไม่จำเป็น

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม