ฉันคิดไม่ออกว่า?:
จะทำอย่างไรในกรณีนี้
val list = mutableList ?: mutableListOf()
และเหตุใดจึงสามารถแก้ไขได้
val list = if (mutableList != null) mutableList else mutableListOf()
ฉันคิดไม่ออกว่า?:
จะทำอย่างไรในกรณีนี้
val list = mutableList ?: mutableListOf()
และเหตุใดจึงสามารถแก้ไขได้
val list = if (mutableList != null) mutableList else mutableListOf()
คำตอบ:
TL; DR: หากการอ้างอิงอ็อบเจ็กต์ผลลัพธ์ [ตัวถูกดำเนินการตัวแรก] ไม่null
ถูกส่งคืน มิฉะนั้นค่าของตัวถูกดำเนินการที่สอง (ซึ่งอาจเป็นnull
) จะถูกส่งกลับ
ตัวดำเนินการ Elvisเป็นส่วนหนึ่งของภาษาโปรแกรมหลายภาษาเช่น Kotlin แต่ยังรวมถึง Groovy หรือ C # ฉันพบว่าคำจำกัดความของWikipediaค่อนข้างแม่นยำ:
ในภาษาโปรแกรมคอมพิวเตอร์บางภาษาตัวดำเนินการ Elvis
?:
เป็นตัวดำเนินการไบนารีที่ส่งคืนตัวถูกดำเนินการตัวแรกหากตัวถูกดำเนินการนั้นเป็นtrue
และจะประเมินและส่งคืนตัวถูกดำเนินการตัวที่สอง มันเป็นความแตกต่างจากผู้ประกอบการที่มีเงื่อนไข ternary ,? :
พบในภาษาเหล่านั้น (และอื่น ๆ อีกมากมาย): ผู้ประกอบการเอลวิสเป็นผู้ประกอบ ternary กับตัวถูกดำเนินการที่สองของการละเว้น
สิ่งต่อไปนี้เป็นจริงโดยเฉพาะอย่างยิ่งสำหรับ Kotlin:
ภาษาโปรแกรมคอมพิวเตอร์บางภาษามีความหมายที่แตกต่างกันสำหรับตัวดำเนินการนี้ แทนการถูกดำเนินการครั้งแรกที่มีการผลในแบบบูลนั้นจะต้องส่งผลในการอ้างอิงวัตถุ หากการอ้างอิงอ็อบเจ็กต์ผลลัพธ์ไม่
null
ได้รับการส่งคืน มิฉะนั้นค่าของตัวถูกดำเนินการที่สอง (ซึ่งอาจเป็นnull
) จะถูกส่งกลับ
ตัวอย่าง:
x ?: y // yields `x` if `x` is not null, `y` otherwise.
elvis operator
จะลดลงเป็นอย่างอื่นได้อีก ดี! และคำอธิบายที่ดีขอบคุณ!
ตัวดำเนินการเอลวิสแสดงด้วยเครื่องหมายคำถามตามด้วยเครื่องหมายจุดคู่: ?:
และสามารถใช้กับไวยากรณ์นี้ได้:
first operand ?: second operand
ช่วยให้คุณสามารถเขียนรหัสที่ปลอดภัยและทำงานได้ดังนี้:
หากfirst operand
ไม่เป็นค่าว่างระบบจะส่งคืน หากเป็นค่าว่างระบบsecond operand
จะส่งคืน สามารถใช้เพื่อรับประกันว่านิพจน์จะไม่คืนค่าว่างเนื่องจากคุณจะระบุค่าที่ไม่เป็นค่าว่างได้หากค่าที่ระบุเป็นค่าว่าง
ตัวอย่างเช่น (ใน Kotlin):
fun retrieveString(): String { //Notice that this type isn't nullable
val nullableVariable: String? = getPotentialNull() //This variable may be null
return nullableVariable ?: "Secondary Not-Null String"
}
ในกรณีนี้หากค่าที่คำนวณgetPotentialNull
ไม่ได้เป็นค่าว่างจะถูกส่งกลับโดยretrieveString
; ถ้าเป็นโมฆะนิพจน์ที่สอง"Secondary Not-Null String"
จะถูกส่งกลับแทน
นอกจากนี้โปรดทราบว่านิพจน์ด้านขวามือจะได้รับการประเมินก็ต่อเมื่อด้านซ้ายมือเป็นค่าว่างโมฆะ
ใน Kotlin คุณสามารถใช้นิพจน์ใดก็ได้second operand
เช่นthrow Exception
นิพจน์
return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")
ชื่อผู้ประกอบการเอลวิสมาจากการที่มีชื่อเสียงนักร้องชาวอเมริกันเอลวิสเพรสลีย์ ทรงผมของเขาคล้ายกับเครื่องหมายคำถาม
ที่มา: Wojda, I. Moskala, M. การพัฒนา Android ด้วย Kotlin 2560. Packt Publishing
สิ่งนี้เรียกว่าตัวดำเนินการเอลวิสและทำ ... ตรงกับที่คุณอธิบายไว้ในคำถามของคุณ หากด้านซ้ายมือเป็นnull
ค่าจะส่งกลับด้านขวาแทนโดยจัดเรียงเป็นทางเลือก มิฉะนั้นจะส่งกลับค่าทางด้านซ้ายมือ
a ?: b
if (a != null) a else b
เป็นเพียงการจดชวเลข
ตัวอย่างเพิ่มเติมพร้อมประเภท:
val x: String? = "foo"
val y: String = x ?: "bar" // "foo", because x was non-null
val a: String? = null
val b: String = a ?: "bar" // "bar", because a was null
a != null ? a : b
ลองมาดูคำจำกัดความ :
เมื่อเรามีการอ้างอิงที่เป็นโมฆะเราสามารถพูดได้ว่า "ถ้า r ไม่ใช่ค่าว่างให้ใช้หรือใช้ค่าที่ไม่ใช่ค่าว่าง x":
?:
(Elvis) หลีกเลี่ยงการใช้คำฟุ่มเฟือยและทำให้โค้ดของคุณกระชับ
ตัวอย่างเช่นฟังก์ชันส่วนขยายคอลเล็กชันจำนวนมากจะคืนค่าnull
เป็นทางเลือก
listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")
?:
ช่วยให้คุณสามารถจัดการกับกรณีสำรองได้อย่างดีเยี่ยมแม้ว่าคุณจะมีทางเลือกหลายชั้น ในกรณีนี้คุณสามารถเชื่อมโยงตัวดำเนินการ Elvis แบบทวีคูณได้ดังนี้:
val l = listOf(1, 2, 3)
val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")
หากคุณจะแสดงสิ่งเดียวกันกับ if else รหัสจะเป็นจำนวนมากซึ่งอ่านยากกว่า
เราสามารถพูดได้ว่าคุณมีสองมือ อยากทราบว่าตอนนี้มือซ้ายของคุณใช้งานได้หรือไม่. ถ้ามือซ้ายไม่ทำงานreturn
empty
อย่างอื่นbusy
ตัวอย่างสำหรับ Java:
private int a;
if(a != null){
println("a is not null, Value is: "+a)
}
else{
println("a is null")
}
ตัวอย่างสำหรับ Kotlin:
val a : Int = 5
val l : Int = if (a != null) a.length else "a is null"
โดยทั่วไปหากด้านซ้ายของ Elvis ส่งคืนค่าว่างด้วยเหตุผลบางประการให้ส่งกลับด้านขวาแทน
กล่าวคือ
val number: Int? = null
println(number ?: "Number is null")
ดังนั้นหากตัวเลขไม่เป็นค่าว่างระบบจะพิมพ์หมายเลขมิฉะนั้นจะพิมพ์ "Number is null"
ตัวดำเนินการ elvis ใน Kotlin ใช้เพื่อความปลอดภัยที่เป็นโมฆะ
x = a ?: b
ในโค้ดข้างต้นx
จะถูกกำหนดค่าของa
ถ้าไม่ได้null
และb
ถ้าเป็นa
null
รหัส kotlin ที่เทียบเท่าโดยไม่ใช้ตัวดำเนินการ elvis อยู่ด้านล่าง:
x = if(a == null) b else a
เพิ่มเติมเล็กน้อยแม้ว่านี่คือ
X = A ?: B
X
จะยังคงเป็นnull
ถ้าทั้งสองอย่างA
และB
ประเมินเป็นnull
ดังนั้นหากคุณต้องการX
เป็นเสมอnon-null
ตรวจสอบให้แน่ใจว่าB
a non-null
หรือที่B
ประเมินเสมอnon-null
ว่าเป็นฟังก์ชันหรือนิพจน์