Apa?: Lakukan di Kotlin? (Operator Elvis)

98

Saya tidak tahu apa yang ?:terjadi dalam contoh kasus ini

val list = mutableList ?: mutableListOf() 

dan mengapa itu bisa diubah menjadi ini

val list = if (mutableList != null) mutableList else mutableListOf()
Jocas
sumber
5
Kembalikan sisi kiri jika bukan nol, jika tidak kembalikan sisi kanan. Ekspresi pertama adalah notasi singkat untuk ekspresi kedua. kotlinlang.org/docs/reference/null-safety.html#elvis-operator
Eugen Pechanec

Jawaban:

115

TL; DR: Jika referensi objek yang dihasilkan [operan pertama] tidak null, akan dikembalikan. Jika tidak, nilai operan kedua (yang mungkin null) dikembalikan


The Operator Elvis adalah bagian dari banyak bahasa pemrograman, misalnya Kotlin tetapi juga Groovy atau C #. Menurut saya definisi Wikipedia cukup akurat:

Dalam bahasa pemrograman komputer tertentu, operator Elvis ?: adalah operator biner yang mengembalikan operan pertamanya jika operan itu adalah true, dan sebaliknya mengevaluasi dan mengembalikan operan keduanya. Ini adalah varian dari operator kondisional terner , ? :, ditemukan di bahasa-bahasa (dan banyak lainnya): operator Elvis adalah operator ternary dengan operan kedua dihilangkan .

Hal berikut ini terutama berlaku untuk Kotlin:

Beberapa bahasa pemrograman komputer memiliki semantik yang berbeda untuk operator ini. Alih-alih operan pertama harus menghasilkan boolean, itu harus menghasilkan referensi objek . Jika referensi objek yang dihasilkan tidak null, akan dikembalikan. Jika tidak, nilai operan kedua (yang mungkin null) dikembalikan.

Sebuah contoh:

x ?: y // yields `x` if `x` is not null, `y` otherwise.
s1m0nw1
sumber
3
Ini sangat keren. Saya tidak pernah berpikir elvis operatorbisa direduksi menjadi sesuatu yang lain. bagus! Dan penjelasan yang bagus, terima kasih!
sud007
88

The Elvis Operator diwakili oleh tanda tanya diikuti oleh titik dua: ?:dan dapat digunakan dengan sintaks ini:

first operand ?: second operand

Ini memungkinkan Anda untuk menulis kode consise, dan berfungsi sebagai berikut:

Jika first operand tidak null , maka itu akan dikembalikan. Jika nilainya null , maka second operandakan dikembalikan. Ini dapat digunakan untuk menjamin bahwa ekspresi tidak akan mengembalikan nilai null, karena Anda akan memberikan nilai bukan null jika nilai yang diberikan adalah null.


Misalnya (di 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"
}

Dalam kasus ini, jika nilai yang dihitung dari getPotentialNullbukan null, itu akan dikembalikan oleh retrieveString; Jika nilainya nol, ekspresi kedua "Secondary Not-Null String"akan dikembalikan.

Perhatikan juga bahwa ekspresi sisi kanan dievaluasi hanya jika sisi kiri adalah null .

Di Kotlin, Anda dapat menggunakan ekspresi apa pun seperti second operand, seperti throw Exceptionekspresi

return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")

Nama Elvis Operator berasal dari penyanyi terkenal Amerika Elvis Presley . Gaya rambutnya menyerupai Tanda Tanya

Elvis QuestionMark

Sumber: Wojda, I. Moskala, M. Pengembangan Android dengan Kotlin. 2017. Penerbitan Packt

LeoColman
sumber
84
Ditambah 1 untuk ilustrasi Mr Presley
s1m0nw1
7
? :) (lihat saat Elvis tersenyum)
LeoColman
1
Setelah beberapa saat, saya tidak mengerti mengapa disebut Operator Elvis. Ilustrasi Anda membuat saya tahu mengapa disebut Operator Elvis. :)
Yohanes AI
apakah cerita tentang Elvis itu benar? haha
Hillcow
@Kerooker Dia tidak tersenyum,?: | akan IMO yang lebih baik.
ahmed galal
38

Ini disebut operator Elvis dan memang ... Persis seperti yang Anda jelaskan dalam pertanyaan Anda. Jika sisi kiri adalah sebuah nullnilai, ia mengembalikan sisi kanan sebagai gantinya, semacam fallback. Jika tidak, itu hanya mengembalikan nilai di sisi kiri.

a ?: bhanyalah singkatan dari if (a != null) a else b.

Beberapa contoh lagi dengan tipe:

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
zsmb13
sumber
10
jika Anda berasal dari java, itu lebih merupakan singkatan dari:a != null ? a : b
crgarridos
9

Mari kita lihat definisi tersebut :

Ketika kita memiliki referensi r nullable, kita dapat mengatakan "jika r bukan null, gunakan itu, jika tidak, gunakan beberapa nilai non-null x":

Itu ?: (Elvis) menghindari verbositas dan membuat kode Anda sangat ringkas.

Misalnya, banyak fungsi ekstensi collection yang dikembalikan nullsebagai fallback.

listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")

?:memberi Anda cara untuk menangani kasus fallback dengan anggun bahkan jika Anda memiliki beberapa lapisan fallback. Jika demikian, Anda cukup menghubungkan banyak operator Elvis, seperti di sini:

val l = listOf(1, 2, 3)

val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")

Jika Anda akan mengungkapkan hal yang sama dengan jika lain itu akan menjadi lebih banyak kode yang lebih sulit untuk dibaca.

Willi Mentzel
sumber
3

Sederhananya kami dapat mengatakan bahwa, Anda memiliki dua tangan. Anda ingin tahu, apakah tangan kiri Anda sedang bekerja? Jika tangan kiri tidak berfungsi, return emptylainbusy

Contoh untuk Java:

private int a;
if(a != null){
    println("a is not null, Value is: "+a)
}
else{
    println("a is null")
}

Contoh untuk Kotlin:

val a : Int = 5
val l : Int = if (a != null) a.length else "a is null"
Romman
sumber
Suka jawaban ini. Terlalu bersih untuk dimengerti.
Gk Mohammad Emon
2

Pada dasarnya, jika sisi kiri Elvis mengembalikan nol karena suatu alasan, mengembalikan sisi kanan sebagai gantinya.

yaitu

val number: Int? = null
println(number ?: "Number is null")

Jadi, jika angka TIDAK nol , itu akan mencetak angka, jika tidak akan mencetak "Nomor adalah null".

pauloaap
sumber
1

Operator elvis di Kotlin digunakan untuk keamanan nol.

x = a ?: b

Pada kode di atas, xakan diberikan nilai aif a nulldan bif ais null.

Kode kotlin yang setara tanpa menggunakan operator elvis adalah di bawah ini:

x = if(a == null) b else a
Abhishek A Udupa
sumber
1

Sedikit tambahan adalah ini

X = A ?: B

Xakan tetap nulljika keduanya Adan Bmengevaluasi kenull

Oleh karena itu, jika Anda ingin Xselalu menjadi non-null, pastikan Bselalu a non-nullatau yang Bselalu mengevaluasi non-nullapakah itu fungsi atau ekspresi.

Wilson
sumber