Swift if let statement di Kotlin

123

Di Kotlin, apakah ada yang setara dengan kode Swift di bawah ini?

if let a = b.val {

}
else {

}
iori24
sumber

Jawaban:

255

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.

marstran
sumber
41
Itu tidak setara. atidak dapat diakses di dalam letdan rundiblokir.
Jacky Choi
6
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.
marstran
1
Kode cepat menyelesaikan tugas asebelum blok kode tersebut. Dan abisa diakses di dalam.
Jacky Choi
1
Untuk apa itu ditugaskan a? Jika ya b, maka itmelayani tujuan yang sama persis. Apakah itu menetapkan ulang adengan hasil val-block?
marstran
3
Anda hanya dapat mengakses 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.
marstran
51

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.

Marko Topolnik
sumber
11

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
}
Wu Yuan Chun
sumber
Menggunakan letbukannya alsoberarti runblok akan dieksekusi setiap kali letblok kembali null, yang bukan itu yang kita inginkan.
Marko Topolnik
6

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

Shahzin KS
sumber
Ini hanya berfungsi jika b adalah variabel lokal. Bagaimana dengan variabel kelas?
Warpzit
5

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 1if-let pernyataan 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  */

masukkan deskripsi gambar di sini

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.

Andy Fedoroff
sumber
4

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"
}
Александр Яковенко
sumber
jika nama == kode nol di {} jangan dijalankan, jika nama sebagai String - kode dieksekusi: nameUnwrapp == nama.
Александр Яковенко
1
Saya tidak berpikir ini yang diminta OP, saya yakin OP sudah tahu apa 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.
kalehv
2

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.

noamtm
sumber
0

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

Richard
sumber
1
Perlu diketahui bahwa pendekatan yang Anda tunjukkan tidak dapat dikompilasi saat ini. Ini hanya saran tentang cara mengubah bahasa Kotlin untuk mengatasi masalah ini. Karenanya, ini bukanlah solusi yang valid.
Peter F
0

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 }
}
Tuan Codesalot
sumber
-1

Pilihan terbersih menurut saya adalah ini

Cepat:

if let a = b.val {

} else {

}

Kotlin

b.val.also { a ->

} ?: run {

}
Stiiv
sumber
-1

Swift if let statement di Kotlin

Jawaban singkatnya adalah gunakan sederhana IF-ELSE karena pada saat komentar ini tidak ada padanannya di Kotlin LET,

    if(A.isNull()){
// A is null
    }else{
// A is not null
    }
bastami82
sumber