Jawaban:
Anda dapat menggunakan let-fungsi seperti ini:
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
Perhatikan bahwa Anda perlu memanggil runfungsi tersebut hanya jika Anda memerlukan blok kode. Anda dapat menghapus run-block jika Anda hanya memiliki satu perjalanan setelah elvis-operator ( ?:).
Ketahuilah bahwa runblok akan dievaluasi baik jika bnol, atau jika let-block bernilai null.
Karena itu, biasanya Anda hanya menginginkan ifekspresi.
val a = if (b == null) {
// ...
} else {
// ...
}
Dalam kasus ini, else-block hanya akan dievaluasi jika bbukan null.
abelum ditentukan di dalam ruang lingkup letdan run. Tetapi Anda dapat mengakses nilai bdi dalam letdengan parameter implisit it. Kurasa ini melayani tujuan yang sama.
asebelum blok kode tersebut. Dan abisa diakses di dalam.
a? Jika ya b, maka itmelayani tujuan yang sama persis. Apakah itu menetapkan ulang adengan hasil val-block?
itdari dalam letblok. Hasil dari blok letatau runakan ditetapkan ke a. Hasilnya adalah ekspresi terakhir di blok tersebut. Anda menggunakan tugas setelah let / runselesai, seperti yang Anda lakukan dengan tugas normal lainnya.
Pertama-tama, pastikan kita memahami semantik dari idiom Swift yang disediakan:
if let a = <expr> {
// then-block
}
else {
// else-block
}
Artinya ini: "jika <expr>hasilnya adalah opsional non-nil, masukkan then-block dengan simbol aterikat ke nilai yang tidak dibungkus. Jika tidak, masukkan elseblok.
Terutama perhatikan bahwa hanyaa terikat di dalam then-block . Di Kotlin, Anda bisa dengan mudah mendapatkan ini dengan menelepon
<expr>?.also { a ->
// then-block
}
dan Anda dapat menambahkan else-block seperti ini:
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
Ini menghasilkan semantik yang sama dengan idiom Swift.
Jawaban saya benar-benar merupakan tiruan kucing dari yang lain. Namun, saya tidak dapat memahami ekspresi mereka dengan mudah. Jadi saya rasa alangkah baiknya memberikan jawaban yang lebih bisa dimengerti.
Dengan cepat:
if let a = b.val {
//use "a" as unwrapped
}
else {
}
Di Kotlin:
b.val?.let{a ->
//use "a" as unwrapped
} ?: run{
//else case
}
letbukannya alsoberarti runblok akan dieksekusi setiap kali letblok kembali null, yang bukan itu yang kita inginkan.
Tidak seperti Swift, Tidak perlu membuka bungkus opsional sebelum menggunakannya di Kotlin. Kita bisa saja memeriksa apakah nilainya bukan null dan kompilator melacak informasi tentang pemeriksaan yang Anda lakukan dan mengizinkan untuk menggunakannya sebagai tidak terbungkus.
Di Swift:
if let a = b.val {
//use "a" as unwrapped
} else {
}
Di Kotlin:
if b.val != null {
//use "b.val" as unwrapped
} else {
}
Lihat Dokumentasi: (null-safety) untuk lebih banyak kasus penggunaan seperti itu
if let pernyataan.Swift Optional Binding(yang disebut if-letpernyataan) digunakan untuk mencari tahu apakah sebuah opsional berisi nilai, dan jika demikian, untuk membuat nilai itu tersedia sebagai konstanta atau variabel sementara. Jadi, Optional Bindinguntuk if-letpernyataannya adalah sebagai berikut:
if-letPernyataan Swift :
let b: Int? = 50
if let a = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
Di Kotlin, seperti di Swift, untuk menghindari error yang disebabkan oleh mencoba mengakses nilai null yang tidak diharapkan, sintaks khusus (seperti b.let { }di contoh kedua) disediakan untuk membuka bungkusan dengan benar nullable types:
Kotlin setara dengan 1
if-letpernyataan Swift :
val b: Int? = null
val a = b
if (a != null) {
println("Good news!")
} else {
println("Equal to 'null' or not set")
}
/* RESULT: Equal to 'null' or not set */
letFungsi Kotlin , jika digunakan bersama dengan operator safe-call ?:, menyediakan cara yang ringkas untuk menangani ekspresi nullable.
Kotlin setara dengan 2 (Fungsi inline let dan Operator Elvis) dari
if-letpernyataan Swift :
val b: Int? = null
val a = b.let { nonNullable -> nonNullable } ?: "Equal to 'null' or not set"
println(a)
/* RESULT: Equal to 'null' or not set */
guard let pernyataan.guard-letpernyataan di Swift sederhana dan kuat. Ia memeriksa beberapa kondisi dan jika dinilai salah, maka elsepernyataan dieksekusi yang biasanya akan keluar dari metode.
Mari jelajahi
guard-letpernyataan Swift :
let b: Int? = nil
func testIt() {
guard let a = b else {
print("Equal to 'nil' or not set")
return
}
print("Good news!")
}
testIt()
/* RESULT: Equal to 'nil' or not set */
Efek serupa Kotlin dari
guard-letpernyataan Swift :
Tidak seperti Swift, di Kotlin, tidak ada pernyataan penjaga sama sekali. Namun, Anda dapat menggunakan Elvis Operator- ?:untuk mendapatkan efek yang serupa.
val b: Int? = 50
fun testIt() {
val a = b ?: return println("Equal to 'null' or not set")
return println("Good news!")
}
testIt()
/* RESULT: Good news! */
Semoga ini membantu.
Berikut cara hanya mengeksekusi kode saat namebukan null:
var name: String? = null
name?.let { nameUnwrapp ->
println(nameUnwrapp) // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
println(nameUnwrapp) // printed "Alex"
}
let, tetapi pertanyaannya adalah tentang elsestrategi yang dijalankan jika objek yang letdipanggil adalah null. Swift melakukannya dengan cara yang lebih alami (bisa diperdebatkan). Tetapi setelah melakukan banyak hal baik Kotlin dan Swift, saya berharap Kotlin membuka bungkusan sederhana seperti yang dilakukan Swift.
Inilah varian saya, terbatas pada kasus "jika tidak null" yang sangat umum.
Pertama-tama, tentukan ini di suatu tempat:
inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
if (obj != null) {
block(obj)
}
}
Mungkin seharusnya begitu internal , untuk menghindari konflik.
Sekarang, ubah kode Swift ini:
if let item = obj.item {
doSomething(item)
}
Untuk kode Kotlin ini:
ifNotNull(obj.item) { item ->
doSomething(item)
}
Perhatikan bahwa seperti biasa dengan blok di Kotlin, Anda dapat melepaskan argumen dan menggunakan it:
ifNotNull(obj.item) {
doSomething(it)
}
Tetapi jika pemblokirannya lebih dari 1-2 baris, sebaiknya eksplisitkan.
Ini mirip dengan Swift yang bisa saya temukan.
Ada cara serupa di kotlin untuk mencapai gaya if-let Swift
if (val a = b) {
a.doFirst()
a.doSecond()
}
Anda juga dapat menetapkan beberapa nilai nullable
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
Pendekatan semacam ini akan lebih cocok jika nilai nullable digunakan lebih dari 1 kali. Menurut saya, ada baiknya dari aspek kinerja karena nilai nullable hanya akan diperiksa satu kali.
sumber: Diskusi Kotlin
Saya menambahkan jawaban ini untuk memperjelas jawaban yang diterima karena terlalu besar untuk komentar.
Pola umum di sini adalah Anda dapat menggunakan kombinasi Scope Functions yang tersedia di Kotlin yang dipisahkan oleh Operator Elvis seperti ini:
<nullable>?.<scope function> {
// code if not null
} :? <scope function> {
// code if null
}
Sebagai contoh:
val gradedStudent = student?.apply {
grade = newGrade
} :? with(newGrade) {
Student().apply { grade = newGrade }
}
atidak dapat diakses di dalamletdanrundiblokir.