Elvis Operator: คืออะไร ไวยากรณ์ และการจัดการค่า null

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

Elvis Operator เป็นตัวดำเนินการแบบไบนารีที่ส่งคืนตัวถูกดำเนินการด้านซ้ายหากไม่ใช่ null และส่งคืนด้านขวามิฉะนั้น เขียนด้วย ?: ใน Kotlin, Groovy และภาษาอื่นๆ ตาม Kotlin Language Documentation, 2024 ตัวดำเนินการนี้เป็นส่วนหนึ่งของระบบ null safety ของภาษาและช่วยลดโครงสร้างแบบมีเงื่อนไขให้เหลือเพียงบรรทัดเดียวโดยไม่สูญเสียความสามารถในการอ่าน แตกต่างจาก if-else แบบเต็ม Elvis Operator จะคำนวณส่วนด้านขวาเฉพาะเมื่อด้านซ้ายเป็น null ซึ่งให้ข้อได้เปรียบด้านประสิทธิภาพเมื่อใช้นิพจน์เริ่มต้นที่ซับซ้อน

สาระสำคัญ

  • Elvis Operator — ตัวดำเนินการ ?: ที่ส่งคืนตัวถูกดำเนินการที่ไม่ใช่ null ตัวแรกจากสองตัว
  • Null safety — พื้นที่การใช้งานหลักของ Elvis Operator ใน Kotlin และภาษาอื่นๆ
  • ไวยากรณ์ กระชับที่สุด: val result = a ?: b เทียบเท่ากับ if (a != null) a else b
  • Groovy ใช้ไวยากรณ์ ?: เดียวกัน Swift — ตัวดำเนินการ ??, Dart — ??
  • การล็อก ผ่าน Elvis Operator เป็นแพทเทิร์นยอดนิยม: val name = input ?: “default”

Elvis Operator คืออะไร

Elvis Operator เป็นตัวดำเนินการแบบไบนารีที่ตั้งชื่อตามทรงผมของ Elvis Presley สัญลักษณ์ ?: มีลักษณะคล้ายใบหน้าของนักร้องเมื่อมองจากด้านข้าง: เครื่องหมายคำถามคือดวงตาและจอน เครื่องหมายโคลอนคือปาก ตัวดำเนินการรับตัวถูกดำเนินการสองตัว: หากตัวแรกไม่ใช่ null จะส่งคืนตัวนั้น มิฉะนั้นจะส่งคืนตัวที่สอง ทำให้สามารถแทนที่โครงสร้าง if-else แบบเต็มด้วยการเขียนสั้นๆ เพียงบรรทัดเดียว

ที่มาของชื่อ

ชื่อ “Elvis Operator” ถูกนำมาใช้ในชุมชน Kotlin และ Groovy จากนั้นจึงแพร่หลายไปยัง Xtend และภาษา JVM อื่นๆ ใน Swift และ Dart โครงสร้างที่คล้ายกันเรียกว่า nil-coalescing operator แต่ทำงานเหมือนกันในเชิงหน้าที่ การเชื่อมโยงทางสายตากับ Elvis Presley ช่วยให้ตัวดำเนินการนี้กลายเป็นหนึ่งในสัญลักษณ์ที่จดจำได้ง่ายที่สุดในไวยากรณ์ของภาษาโปรแกรมสมัยใหม่

บทบาทในการจัดการค่า null

Elvis Operator เป็นส่วนหนึ่งของระบบ null safety ที่ป้องกัน NullPointerException (NPE) จากการวิจัยของ JetBrains ในปี 2023 NPE คิดเป็น 28% ของข้อยกเว้นทั้งหมดในโค้ด production บน JVM การใช้ Elvis Operator ช่วยขจัด NPE ณ จุดกำหนดค่าโดยสิ้นเชิง รับประกันค่าเริ่มต้น เมื่อรวมกับตัวดำเนินการ safe call ?. จะได้เชนที่เชื่อถือได้โดยไม่มีบล็อก if แม้แต่บล็อกเดียว

ไวยากรณ์ Elvis Operator ใน Kotlin

ใน Kotlin Elvis Operator เขียนด้วย ?: ระหว่างสองนิพจน์ หากนิพจน์ด้านซ้ายไม่ใช่ null ผลลัพธ์จะเท่ากับด้านซ้าย มิฉะนั้นจะคำนวณด้านขวา นิพจน์ด้านขวาจะถูกคำนวณแบบขี้เกียจ — เฉพาะเมื่อตัวถูกดำเนินการด้านซ้ายเป็น null ซึ่งสำคัญต่อประสิทธิภาพเมื่อใช้การคำนวณที่ซับซ้อนหรือการเรียกใช้ API

kotlin
val name: String? = getUserName()
val displayName = name ?: "Guest"

fun getLength(str: String?): Int {
    return str?.length ?: 0
}

val config: Config? = loadConfig()
val timeout = config?.timeout ?: 30
println("หมดเวลา: $timeout")

// Elvis แบบ throw สำหรับพารามิเตอร์ที่จำเป็น
val requiredId = nullableId ?: throw IllegalArgumentException("ID is required")

// Elvis แบบ return สำหรับการออกก่อนกำหนด
fun process(data: String?): Result {
    val safe = data ?: return Result.failure("No data")
    return processInternal(safe)
}

การรวมกับ let เป็นแพทเทิร์นที่พบบ่อยใน Kotlin โดย Elvis Operator กำหนดค่าเริ่มต้น และ let ดำเนินการกับผลลัพธ์ที่ไม่ใช่ null วิธีการนี้แทนที่บล็อก if-else ทั้งหมดด้วยเชนการเรียกใช้เดียวโดยไม่สูญเสียความสามารถในการอ่าน Elvis Operator ยังสามารถใช้กับ throw เพื่อบังคับให้หยุดเมื่อไม่มีพารามิเตอร์ที่จำเป็น — นี่คือวิธีที่ถูกต้องตามสำนวนในการตรวจสอบข้อมูลนำเข้า

Elvis แบบออกจากฟังก์ชันก่อนกำหนด

ใน Kotlin มีแพทเทิร์น Elvis + return ที่แพร่หลาย หากค่าเป็น null ฟังก์ชันจะส่งคืนผลลัพธ์หรือโยนข้อยกเว้นทันที สำนวน “Elvis with return” มักใช้ในฟังก์ชันแปลงข้อมูล: val processed = rawData ?: return defaultValue ซึ่งกระชับกว่า guard let ใน Swift และไม่เพิ่มความลึกของการซ้อนโค้ด

Elvis Operator vs if-else: การเปรียบเทียบ

Elvis Operator สั้นกว่า if-else และไม่ต้องเขียนตัวแปรซ้ำ เปรียบเทียบ: val x = a ?: b กับ val x = if (a != null) a else b เมื่อใช้นิพจน์ที่ซับซ้อน การลดโค้ดสามารถสูงถึง 60% โดยความหมายยังคงเหมือนกันทุกประการ — คอมไพเลอร์สามารถสร้าง byte-code ที่เหมือนกันสำหรับทั้งสองแบบ

เกณฑ์Elvis Operatorif-else
ความยาวของการเขียน1 บรรทัด, 5–10 ตัวอักษร3 บรรทัด, 15–30 ตัวอักษร
การเขียนนิพจน์ซ้ำไม่ใช่ (a != null) ? a : b
ความขี้เกียจของด้านขวาใช่ใช่ (elvis สั้นกว่า)
ผลข้างเคียงเฉพาะด้านขวาทั้งสองสาขา
ความสามารถในการอ่านสูงสำหรับกรณีง่ายดีกว่าสำหรับตรรกะซับซ้อน

เมื่อใดควรใช้ Elvis Operator

Elvis Operator เหมาะที่สุดสำหรับการกำหนดค่าเริ่มต้น การเรียกเชนฟังก์ชันด้วยการเข้าถึงแบบปลอดภัย และการล็อกค่าที่ขาดหายไป แพทเทิร์นที่ถูกต้องตามสำนวน ของ Kotlin แนะนำให้ใช้แทน if-else สำหรับการตรวจสอบ null อย่างง่ายในนิพจน์ เมื่อรวมกับ ?. จะให้เชนที่กระชับโดยไม่ต้องมีตัวแปรชั่วคราว

เมื่อใด if-else เหมาะสมกว่า

if-else ยังคงเหมาะสมกว่าเมื่อมีเงื่อนไขหลายเงื่อนไข ต้องการดำเนินการผลข้างเคียง หรือเมื่อตัวถูกดำเนินการทั้งสองเป็น บล็อกโค้ดที่ซับซ้อน ที่มีการดำเนินการหลายอย่าง Elvis Operator ไม่รองรับบล็อกซ้อน — รองรับเฉพาะนิพจน์เดี่ยวสำหรับแต่ละตัวถูกดำเนินการ หากด้านขวาเรียกใช้ฟังก์ชันที่มีผลข้างเคียง ความสามารถในการอ่านของ if-Else จะสูงกว่า

Elvis Operator ในภาษาโปรแกรมอื่นๆ

Groovy ใช้ไวยากรณ์ ?: เหมือนกับ Kotlin ทุกประการ เนื่องจากทั้งสองภาษาทำงานบน JVM และใช้ปรัชญา null-safety ร่วมกัน ใน Groovy ตัวดำเนินการนี้ปรากฏก่อน — มีในภาษาตั้งแต่เวอร์ชัน 1.8 ที่เผยแพร่ในปี 2011 Groovy ยังรองรับการกำหนดค่าแบบ Elvis: x ?= value (กำหนดค่าเฉพาะเมื่อ x เป็น null)

groovy
def name = getUserName()
def display = name ?: "Guest"

def map = ["key": "value"]
def result = map?.get("missing") ?: "default"
println(result)

// การกำหนดค่า Elvis ใน Groovy
def config = null
config ?= "defaultConfig"
assert config == "defaultConfig"

ใน Swift สิ่งที่เทียบเท่าเรียกว่า nil-coalescing operator และเขียนด้วย ?? ใน Dart ใช้ไวยากรณ์ ?? เช่นเดียวกัน ความแตกต่างคือ Swift และ Dart ต้องการให้ประเภทของตัวถูกดำเนินการตรงกัน ในขณะที่ Kotlin อนุญาตให้มีประเภทต่างกันโดยปรับเป็น supertype ร่วมกันโดยอัตโนมัติ ใน TypeScript ตั้งแต่เวอร์ชัน 3.7 มีตัวดำเนินการ ?? (nullish coalescing) ซึ่งทำงานกับ null และ undefined เท่านั้น ต่างจาก || ที่กรองค่า falsy ทั้งหมด ใน PHP ตั้งแต่เวอร์ชัน 7.0 มีตัวดำเนินการ ?? ใน C# — ?? ตั้งแต่เวอร์ชัน 6.0

ข้อผิดพลาดทั่วไปกับ Elvis Operator

ข้อผิดพลาดที่พบบ่อยที่สุดคือการสับสนระหว่าง Elvis Operator ?: กับตัวดำเนินการ safe call ?. ใน Kotlin ?. เรียกใช้เมธอดหรือคุณสมบัติเฉพาะเมื่อวัตถุไม่ใช่ null ในขณะที่ ?: ส่งคืนค่าเริ่มต้นเมื่อเป็น null สามารถใช้ร่วมกันตามลำดับได้ แต่แต่ละตัวทำหน้าที่ของตนเอง ความสับสนเกิดขึ้นกับผู้เริ่มต้นที่พยายามใช้ ?: โดยไม่มี ?. นำหน้า

ผลข้างเคียงในตัวถูกดำเนินการด้านขวา

ส่วนด้านขวาของ Elvis คำนวณแบบขี้เกียจ แต่หากมีการเรียกใช้ฟังก์ชันที่มี ผลข้างเคียง อาจนำไปสู่พฤติกรรมที่ไม่คาดคิด นักพัฒนาบางครั้งใส่การคำนวณที่ซับซ้อนหรือการล็อกไว้ในด้านขวา ซึ่งจะไม่ถูกดำเนินการเมื่อค่าไม่ใช่ null สิ่งสำคัญคือต้องจำไว้ว่าส่วนด้านขวาคคือนิพจน์ที่จะคำนวณเมื่อจำเป็นเท่านั้น

เชน Elvis โดยไม่จัดกลุ่ม

การมี Elvis หลายตัวต่อเนื่องกันอาจทำให้การอ่านโค้ดซับซ้อนขึ้น ตัวอย่างเช่น a ?: b ?: c ?: d ทำงานจากซ้ายไปขวา ส่งคืนค่าที่ไม่ใช่ null ตัวแรก การจัดกลุ่ม ด้วยวงเล็บหรือการแยกตรรกะออกเป็นฟังก์ชันแยกต่างหากช่วยเพิ่มความสามารถในการอ่านและทำให้การดีบักง่ายขึ้น หากเชนยาวเกิน 3 องค์ประกอบ ควรใช้นิพจน์ when หรือฟังก์ชันช่วย

Elvis แทน if-else สำหรับเงื่อนไขบูลีน

นักพัฒนามือใหม่บางครั้งพยายามใช้ Elvis Operator เพื่อตรวจสอบ ค่าบูลีน: val x = flag ?: false วิธีนี้จะทำงานก็ต่อเมื่อ flag สามารถเป็น null ได้ สำหรับเงื่อนไขบูลีนที่ไม่มี null ต้องใช้ if-else ปกติหรือเทอร์นารีโอเปอเรเตอร์ ซึ่งไม่มีใน Kotlin แต่ถูกแทนที่ด้วยนิพจน์ if-else: val x = if (flag) a else b

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

Elvis Operator แตกต่างจากเทอร์นารีโอเปอเรเตอร์อย่างไร?

Elvis Operator ตรวจสอบเฉพาะ null ในขณะที่เทอร์นารีโอเปอเรเตอร์รับเงื่อนไขบูลีนใดๆ ใน Kotlin ไม่มีเทอร์นารีโอเปอเรเตอร์ — ถูกแทนที่ด้วยนิพจน์ if-else Elvis แก้ปัญหาเฉพาะอย่างหนึ่ง: ค่าเริ่มต้นเมื่อเป็น null ในขณะที่เทอร์นารีโอเปอเรเตอร์ครอบคลุมนิพจน์เงื่อนไขทั้งหมด

สามารถใช้ Elvis Operator กับฟังก์ชันได้หรือไม่?

ได้ ด้านขวาสามารถเป็น การเรียกใช้ฟังก์ชัน: val x = a ?: calculateDefault() ฟังก์ชันจะคำนวณเฉพาะเมื่อ a เป็น null เนื่องจากการคำนวณแบบขี้เกียจ ซึ่งช่วยให้ใช้การคำนวณที่ซับซ้อน การเรียกใช้ API หรือการสอบถามฐานข้อมูลได้โดยไม่สูญเสียประสิทธิภาพเมื่อมีค่าอยู่

มี Elvis Operator ใน Java หรือไม่?

ใน Java ไม่มี Elvis Operator โดยตรง ตั้งแต่ Java 8 สามารถใช้ Optional.ofNullable(value).orElse(default) ใน Java 14+ มี switch- expressions แต่ ?: เต็มรูปแบบยังไม่มี Kotlin และ Groovy จัดให้เป็นโครงสร้างไวยากรณ์ในตัวของภาษา

Elvis Operator ทำงานกับเชนการเรียกใช้อย่างไร?

แพทเทิร์นทั่วไป: safe call ?. ตามด้วย Elvis ตัวอย่าง: user?.address?.city ?: “Unknown” หากองค์ประกอบใดในเชนเป็น null จะส่งคืนค่าเริ่มต้น นี่คือการแทนที่การตรวจสอบ if ซ้อนกันอย่างกระชับ ซึ่งลดโค้ดลง 3–5 เท่าเมื่อเทียบกับวิธีการแบบดั้งเดิม

ความแตกต่างระหว่าง Elvis Operator กับ orElse ใน Optional คืออะไร?

Elvis Operator เป็นโครงสร้างไวยากรณ์ในระดับภาษา ส่วน orElse เป็นเมธอดของ Optional ใน Java Elvis ทำงานแบบขี้เกียจ (ด้านขวาคำนวณเฉพาะเมื่อเป็น null) ส่วน orElse คำนวณอาร์กิวเมนต์เสมอ สำหรับเวอร์ชันขี้เกียจใน Java มี orElseGet ที่รับ Supplier Elvis สั้นกว่าและไม่ต้องสร้าง Optional

สรุป

  • Elvis Operator — ตัวดำเนินการ ?: สำหรับกำหนดค่าเริ่มต้นเมื่อตัวถูกดำเนินการเป็น null
  • ไวยากรณ์ ใน Kotlin และ Groovy: val result = a ?: b โดยที่ b จะคำนวณเมื่อ a == null เท่านั้น
  • Null safety — พื้นที่การใช้งานหลักที่ป้องกัน NullPointerException
  • Nil-coalescing — สิ่งที่เทียบเท่าใน Swift (??) และ Dart (??) ที่มีความหมายคล้ายกัน ใน TypeScript — ?? ตั้งแต่เวอร์ชัน 3.7
  • การรวม กับ safe call ?. ให้เชนการจัดการค่า null ที่กระชับโดยไม่ต้องซ้อน
  • การคำนวณแบบขี้เกียจ ของตัวถูกดำเนินการด้านขวา — ความแตกต่างหลักจากเทอร์นารีโอเปอเรเตอร์
  • แนวปฏิบัติที่ดีที่สุด — ใช้สำหรับการตรวจสอบ null อย่างง่าย หลีกเลี่ยงในบล็อกที่ซับซ้อนที่มีผลข้างเคียง

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

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

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

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