Apa yang setara dengan ungkapan ini di Kotlin?
a ? b : c
Ini bukan kode yang valid di Kotlin.
Apa yang setara dengan ungkapan ini di Kotlin?
a ? b : c
Ini bukan kode yang valid di Kotlin.
Jawaban:
Di Kotlin, if
pernyataan adalah ekspresi. Jadi kode berikut ini setara:
if (a) b else c
Perbedaan antara ekspresi dan pernyataan adalah penting di sini. Dalam Java / C # / JavaScript, if
bentuk pernyataan, yang berarti bahwa itu tidak menentukan nilai. Lebih konkretnya, Anda tidak dapat menetapkannya ke variabel.
// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c
Jika Anda berasal dari bahasa di mana if
pernyataan, ini mungkin tampak tidak wajar tetapi perasaan itu harus segera mereda.
when
.
x = a==b
b + if (a) c else d
vs. b + (c if (a) else d)
Yang terakhir membutuhkan kurung tambahan. karena c
tidak tertutup oleh kondisi dan else
.
Anda dapat menentukan Boolean
fungsi ekstensi Anda sendiri yang kembali null
ketika Boolean
adalah false
untuk menyediakan struktur yang mirip dengan operator ternary:
infix fun <T> Boolean.then(param: T): T? = if (this) param else null
Ini akan membuat a ? b : c
ekspresi diterjemahkan menjadi a then b ?: c
, seperti:
println(condition then "yes" ?: "no")
Pembaruan: Tetapi untuk melakukan beberapa saklar kondisional seperti Java, Anda akan memerlukan sesuatu seperti itu
infix fun <T> Boolean.then(param: () -> T): T? = if (this) param() else null
println(condition then { "yes" } ?: "no")
perhatikan lambda. Perhitungan isinya harus ditunda sampai kami pastikan condition
adalahtrue
Yang ini terlihat kikuk, itu sebabnya ada permintaan yang tinggi ada untuk operator pelabuhan ternary Jawa ke Kotlin
infix inline fun<T> Boolean.then(param: ()->T):T? = if(this) param() else null
true then { null } ?: "not-null"
?:
operator di sini adalah elvis-operator
: kotlinlang.org/docs/reference/null-safety.html#elvis-operator
if (a) b else c
adalah apa yang dapat Anda gunakan sebagai ganti ekspresi operator ternary a ? b : c
.
Di Kotlin, banyak pernyataan kontrol termasuk if
, when
atau bahkan try
dapat digunakan sebagai ekspresi . Ini berarti bahwa mereka dapat memiliki hasil yang dapat ditetapkan ke variabel, dikembalikan dari fungsi dll.
Sebagai hasil dari ekspresi Kotlin, bahasa tidak benar-benar membutuhkan operator ternary .
if (a) b else c
adalah apa yang dapat Anda gunakan sebagai ganti ekspresi operator ternary a ? b : c
.
Saya pikir idenya adalah bahwa ekspresi sebelumnya lebih mudah dibaca karena semua orang tahu apa yang ifelse
dilakukan, sedangkan ? :
agak tidak jelas jika Anda belum terbiasa dengan sintaks.
Meskipun demikian, saya harus mengakui bahwa saya sering kehilangan operator ternary yang lebih nyaman.
Alternatif Lainnya
kapan
Anda mungkin juga melihat when
konstruksi yang digunakan di Kotlin ketika kondisinya diperiksa. Ini juga cara untuk mengungkapkan jika-cascade dengan cara alternatif. Berikut ini sesuai dengan contoh PL.
when(a) {
true -> b
false -> c
}
Ekstensi
Seperti banyak contoh yang baik ( Operator Bersyarat Kotlin Ternary ) dalam jawaban lain menunjukkan, ekstensi juga dapat membantu memecahkan kasus penggunaan Anda.
Untuk saya sendiri saya menggunakan fungsi ekstensi berikut:
fun T?.or<T>(default: T): T = if (this == null) default else this
fun T?.or<T>(compute: () -> T): T = if (this == null) compute() else this
Pertama akan mengembalikan asalkan nilai default dalam kasus objek sama dengan nol. Kedua akan mengevaluasi ekspresi yang disediakan dalam lambda dalam kasus yang sama.
Pemakaian:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
Secara pribadi bagi saya kode di atas lebih mudah dibaca daripada if
inlining konstruksi
e.getMessage() ?: "unknown"
. Yang kedua dapat dinyatakan sebagaiobj?.lastMessage?.timestamp ?: { Date() }()
Setara dengan operator terner Jawa
a ? b : c
adalah IF sederhana di Kotlin dalam satu baris
if(a) b else c
tidak ada operator ternary (kondisi? lalu: lain), karena biasa jika berfungsi dengan baik dalam peran ini.
https://kotlinlang.org/docs/reference/control-flow.html#if-expression
Kasus khusus untuk perbandingan Null
Anda dapat menggunakan operator Elvis
if ( a != null ) a else b
// equivalent to
a ?: b
Tidak ada operator ternary di kotlin, karena if else
blok mengembalikan nilai
jadi, Anda bisa melakukan:
val max = if (a > b) a else b
alih-alih javamax = (a > b) ? b : c
Kami juga dapat menggunakan when
konstruksi, juga mengembalikan nilai:
val max = when(a > b) {
true -> a
false -> b
}
Berikut ini tautan untuk dokumentasi kotlin: Aliran Kontrol: if, when, for, while
Di Kotlin,
if
adalah ekspresi, yaitu mengembalikan nilai. Oleh karena itu tidak ada operator ternary(condition ? then : else)
, karena biasa jika berfungsi dengan baik dalam peran ini. sumber manual dari sini
// Traditional usage
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// As expression
val max = if (a > b) a else b
Beberapa kasus sudut tidak disebutkan dalam jawaban lain.
Sejak kemunculan takeIf di Kotlin 1.1 , operator ternary a ? b : c
juga dapat diekspresikan seperti ini:
b.takeIf { a } ?: c
Ini menjadi lebih pendek jika c adalah null
:
b.takeIf { a }
Juga catat bahwa tipikal di dunia Java nol cek seperti value != null ? value : defaultValue
menerjemahkan dalam Kotlin ideomatis menjadi adil value ?: defaultValue
.
Serupa a != null ? b : c
dapat diterjemahkan ke a?.let { b } ?: c
.
b.takeIf { a } ?: c
lebih pendek dan lebih mudah dibaca daripada if (a) b else c
? Operator Terneray tentu saja merupakan fitur yang hilang di Kotlin karena nama variabel dan kondisinya dapat panjang dan membuat Anda membagi garis yang buruk
takeIf
selalu mengevaluasi kasus sebenarnya (di sini a
). Tidak hanya ekspresi itu dapat dihitung secara sia-sia jika a
kebetulan salah, tetapi Anda tidak bisa mendapatkan manfaat dari gips cerdas à la if (a is Int) { a + 3 }
.
{ a }
adalah lambda yang dievaluasi dengan malas.
b
)". Tetapi meski { a }
malas, harus dievaluasi untuk menentukan hasil ekspresi.
Jawa
int temp = a ? b : c;
Setara dengan Kotlin :
var temp = if (a) b else c
TUGAS :
Mari kita perhatikan contoh berikut:
if (!answer.isSuccessful()) {
result = "wrong"
} else {
result = answer.body().string()
}
return result
Kami membutuhkan yang setara di Kotlin berikut:
return (! answer.isSuccessful ())
?
"salah":
answer.body (). string ()
SOLUSI :
1.a . Anda dapat menggunakan if-expression
di Kotlin:
return if (!answer.isSuccessful()) "wrong" else answer.body().string()
1.b . Akan jauh lebih baik jika Anda membalik ini if-expression
(mari kita lakukan tanpa not
):
return if (answer.isSuccessful()) answer.body().string() else "wrong"
2 . Operator Kotlin's Elvis ?:
dapat melakukan pekerjaan dengan lebih baik:
return answer.body()?.string() ?: "wrong"
3 . Atau gunakan Extension function
untuk Answer
kelas yang sesuai :
fun Answer.bodyOrNull(): Body? = if (isSuccessful()) body() else null
4 . Menggunakan Extension function
Anda dapat mengurangi kode berkat Elvis operator
:
return answer.bodyOrNull()?.string() ?: "wrong"
5 . Atau cukup gunakan when
operator:
when (!answer.isSuccessful()) {
parseInt(str) -> result = "wrong"
else -> result = answer.body().string()
}
Semoga ini membantu.
saat mengganti operator sakelar dari bahasa yang mirip C. Dalam bentuk yang paling sederhana terlihat seperti ini
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
when
sebagai pernyataan, bukan ekspresi. Perbandingan yang lebih relevan dengan ekspresi kondisional terner adalah memiliki setiap cabang mengembalikan nilai, sehingga keseluruhan ketika ekspresi mengevaluasi ke nilai (seperti yang terjadi dengan kondisional terner).
Tidak ada operator ternary di Kotlin. Tampaknya bermasalah pada pandangan pertama. Tetapi berpikir kita bisa melakukannya dengan pernyataan inline if else karena ini adalah ekspresi di sini. Yang harus kita lakukan -
var number = if(n>0) "Positive" else "Negetive"
Di sini kita dapat lagi jika memblokir terlalu banyak yang kita butuhkan. Suka-
var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"
Jadi saluran ini sangat sederhana dan lebih mudah dibaca daripada operator ternary. ketika kita menggunakan lebih dari satu operator ternary di java sepertinya mengerikan. Tetapi di sini kita memiliki sintaks yang jelas. bahkan kita bisa menulisnya dalam banyak baris juga.
Anda dapat menggunakannya var a= if (a) b else c
sebagai pengganti operator ternary.
Konsep lain yang baik dari kotlin adalah operator Elvis. Anda tidak perlu memeriksa nol setiap saat.
val l = b?.length ?: -1
Ini akan mengembalikan panjang jika b bukan nol jika tidak dieksekusi pernyataan sisi kanan.
seperti dikutip Drew Noakes, kotlin menggunakan jika pernyataan sebagai ekspresi, sehingga Operator Bersyarat tidak diperlukan lagi,
tetapi dengan fungsi ekstensi dan infix overloading, Anda bisa menerapkannya sendiri, berikut ini contohnya
infix fun <T> Boolean.then(value: T?) = TernaryExpression(this, value)
class TernaryExpression<out T>(val flag: Boolean, val truly: T?) {
infix fun <T> or(falsy: T?) = if (flag) truly else falsy
}
lalu gunakan seperti ini
val grade = 90
val clazz = (grade > 80) then "A" or "B"
Pendekatan lain yang menarik adalah menggunakan when
:
when(a) {
true -> b
false -> b
}
Dapat sangat berguna dalam beberapa skenario yang lebih kompleks. Dan jujur, itu lebih mudah dibaca daripada bagi sayaif ... else ...
Anda dapat melakukannya dengan berbagai cara di Kotlin
Menggunakan if
if(a) b else c
Menggunakan kapan
when (a) {
true -> print("value b")
false -> print("value c")
else -> {
print("default return in any other case")
}
}
Keamanan Null
val a = b ?: c
Tidak ada operasi ternary di Kotlin, tetapi ada beberapa cara yang menyenangkan untuk mengatasinya. Seperti yang telah ditunjukkan orang lain, terjemahan langsung ke Kotlin akan terlihat seperti ini:
val x = if (condition) result1 else result2
Tapi, secara pribadi, saya pikir itu bisa sedikit berantakan dan sulit dibaca. Ada beberapa opsi lain yang dibangun ke perpustakaan. Anda dapat menggunakan takeIf {} dengan operator elvis:
val x = result1.takeIf { condition } ?: result2
Apa yang terjadi di sana adalah bahwa perintah takeIf {} mengembalikan result1 atau null Anda, dan operator elvis menangani opsi nol. Ada beberapa opsi tambahan, takeUnless {}, misalnya:
val x = result1.takeUnless { condition } ?: result2
Bahasanya jelas, Anda tahu apa yang dilakukannya.
Jika ini adalah kondisi yang umum digunakan, Anda juga dapat melakukan sesuatu yang menyenangkan seperti menggunakan metode ekstensi sebaris. Misalnya, kita ingin melacak skor game sebagai Int, dan kami ingin selalu mengembalikan 0 jika kondisi yang diberikan tidak terpenuhi:
inline fun Int.zeroIfFalse(func: () -> Boolean) : Int = if (!func.invoke()) 0 else this
Ok, sepertinya jelek. Tetapi pertimbangkan bagaimana tampilannya ketika digunakan:
var score = 0
val twoPointer = 2
val threePointer = 3
score += twoPointer.zeroIfFalse { scoreCondition }
score += threePointer.zeroIfFalse { scoreCondition }
Seperti yang Anda lihat, Kotlin menawarkan banyak fleksibilitas dalam cara Anda memilih untuk mengekspresikan kode Anda. Ada banyak variasi contoh saya dan mungkin cara yang belum saya temukan. Saya harap ini membantu!
takeIf
memang pilihan favorit saya, sangat elegan.
Ingat operator ternary dan operator Elvis memiliki makna yang berbeda di Kotlin tidak seperti dalam banyak bahasa populer. Melakukan expression? value1: value2
akan memberi Anda kata-kata buruk oleh kompiler Kotlin , tidak seperti bahasa lain karena tidak ada operator ternary di Kotlin seperti yang disebutkan dalam dokumen resmi . Alasannya adalah bahwa pernyataan if, when dan try-catch sendiri mengembalikan nilai.
Jadi, melakukan expression? value1: value2
bisa diganti dengan
val max = jika (a> b) cetak ("Pilih a") cetak lain ("Pilih b")
The Elvis Operator yang Kotlin memiliki, bekerja hanya dalam kasus variabel nullable ex .:
Jika saya melakukan sesuatu seperti
value3 = value1 ?: value2
maka jika value1 adalah null maka value2 akan dikembalikan sebaliknya value1 akan dikembalikan.
Pemahaman yang lebih jelas dapat dicapai dari jawaban-jawaban ini .
Anda dapat menggunakan if
ekspresi untuk ini di Kotlin. Di Kotlin if
adalah ekspresi dengan nilai hasil. Jadi di Kotlin kita bisa menulis
fun max(a: Int, b: Int) = if (a > b) a else b
dan di Jawa kita dapat mencapai hal yang sama tetapi dengan kode yang lebih besar
int max(int a, int b) {
return a > b ? a : b
}
Jika Anda tidak ingin menggunakan notasi standar, Anda juga dapat membuat / mensimulasikannya menggunakan infix dengan sesuatu seperti ini:
buat kelas untuk menampung target dan hasil Anda:
data class Ternary<T>(val target: T, val result: Boolean)
buat beberapa fungsi infiks untuk mensimulasikan operasi ternary
infix fun <T> Boolean.then(target: T): Ternary<T> {
return Ternary(target, this)
}
infix fun <T> Ternary<T>.or(target: T): T {
return if (this.result) this.target else target
}
Maka Anda akan dapat menggunakannya seperti ini:
val collection: List<Int> = mutableListOf(1, 2, 3, 4)
var exampleOne = collection.isEmpty() then "yes" or "no"
var exampleTwo = (collection.isNotEmpty() && collection.contains(2)) then "yes" or "no"
var exampleThree = collection.contains(1) then "yes" or "no"
Pendekatan pendek lain untuk digunakan
val value : String = "Kotlin"
value ?: ""
Di sini kotlin sendiri memeriksa nilai nol dan jika itu nol maka ia melewati nilai string kosong.
Mengapa orang menggunakan sesuatu seperti ini:
when(a) {
true -> b
false -> b
}
ketika Anda benar-benar dapat menggunakan sesuatu seperti ini ( a
dalam hal ini adalah boolean):
when {
a -> b
else -> b
}
? and :
bertentangan dengan deklarasi nullable / type daripada jenis cek. Selain itu, saya tidak melihat alasan. Saya pikir seseorang pasti akan mempertimbangkan, jika ada inline if-else memeriksa kondisi. Mari kita tunggu dan lihat di versi mendatang.
Ketika bekerja dengan apply (), biarkan terasa sangat berguna ketika berhadapan dengan operasi ternary, karena lebih elegan dan memberi Anda ruang
val columns: List<String> = ...
val band = Band().apply {
name = columns[0]
album = columns[1]
year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}
Dengan fungsi infix berikut, saya dapat membahas banyak kasus penggunaan umum dengan cara yang hampir sama dengan yang dapat dilakukan dengan Python:
class TestKotlinTernaryConditionalOperator {
@Test
fun testAndOrInfixFunctions() {
Assertions.assertThat(true and "yes" or "no").isEqualTo("yes")
Assertions.assertThat(false and "yes" or "no").isEqualTo("no")
Assertions.assertThat("A" and "yes" or "no").isEqualTo("yes")
Assertions.assertThat("" and "yes" or "no").isEqualTo("no")
Assertions.assertThat(1 and "yes" or "no").isEqualTo("yes")
Assertions.assertThat(0 and "yes" or "no").isEqualTo("no")
Assertions.assertThat(Date() and "yes" or "no").isEqualTo("yes")
@Suppress("CAST_NEVER_SUCCEEDS")
Assertions.assertThat(null as Date? and "yes" or "no").isEqualTo("no")
}
}
infix fun <E> Boolean?.and(other: E?): E? = if (this == true) other else null
infix fun <E> CharSequence?.and(other: E?): E? = if (!(this ?: "").isEmpty()) other else null
infix fun <E> Number?.and(other: E?): E? = if (this?.toInt() ?: 0 != 0) other else null
infix fun <E> Any?.and(other: E?): E? = if (this != null) other else null
infix fun <E> E?.or(other: E?): E? = this ?: other
Tidak ada operator ternary di Kotlin, yang paling tertutup adalah di bawah dua kasus,
val a = true if(a) print("A is true") else print("A is false")
Jika ekspresi di sebelah kiri?: Bukan nol, operator elvis mengembalikannya, jika tidak, mengembalikan ekspresi ke kanan. Perhatikan bahwa ekspresi sisi kanan dievaluasi hanya jika sisi kiri adalah nol.
val name = node.getName() ?: throw IllegalArgumentException("name expected")
contoh: var energy: Int = data? .get (posisi) ?. energy? .toInt ()?: 0
Dalam Kotlin jika Anda menggunakan :? Itu akan bekerja seperti jika pernyataan itu akan kembali null maka :? 0 akan mengambil 0 atau apa pun yang Anda harus menulis sisi ini.
Di Kotlin Anda dapat menggunakan operasi ternary seperti ini: val x = if(a) "add b" else "add c"
Setelah melakukan riset terhadap ide-ide lain, saya telah menurunkan operator ternary berikut:
infix fun <T : Any> Boolean.yes(trueValue: T): T? = if (this) trueValue else null
infix fun <T : Any> T?.no(falseValue: T): T = this ?: falseValue
Contoh (jalankan di sini ):
fun main() {
run {
val cond = true
val result = cond yes "True!" no "False!"
println("ternary test($cond): $result")
}
run {
val cond = false
val result = cond yes "True!" no "False!"
println("ternary test($cond): $result")
}
}
Versi ini lancar dan tidak bertentangan dengan operator penggabungan nol.
then
bukan yes
.