Cara terbaik untuk mengecek nol di Kotlin?


Jawaban:


63

Kedua pendekatan tersebut menghasilkan bytecode yang sama sehingga Anda dapat memilih apa pun yang Anda inginkan.


4
Jika saya memahaminya dengan benar maka dia meminta cara terbaik untuk memeriksa null di Kotlin, bukan pendekatan mana yang menghasilkan kode byte terbaik. @ Jawaban BenitoBertoli tampak menjanjikan, ini mengurangi kode boilerplate
imGs

156

Kesetaraan struktural a == bditerjemahkan ke

a?.equals(b) ?: (b === null)

Oleh karena itu, bila dibandingkan dengan null, persamaan struktural a == nullditerjemahkan menjadi persamaan referensial a === null.

Menurut dokumen , tidak ada gunanya mengoptimalkan kode Anda, jadi Anda dapat menggunakan a == nulldan a != null


Perhatikan bahwa jika variabel adalah properti yang bisa berubah, Anda tidak akan bisa mentransmisikannya ke tipe non-nullable di dalam ifpernyataan (karena nilainya mungkin telah dimodifikasi oleh utas lain) dan Anda harus menggunakan operator panggilan aman denganlet sebagai gantinya.

Operator panggilan aman ?.

a?.let {
   // not null do something
   println(it)
   println("not null")
}


Anda dapat menggunakannya bersama operator Elvis.

Operator Elvis ?: (Saya menebak karena tanda interogasi terlihat seperti rambut Elvis)

a ?: println("null")

Dan jika Anda ingin menjalankan blok kode

a ?: run {
    println("null")
    println("The King has left the building")
}

Menggabungkan keduanya

a?.let {
   println("not null")
   println("Wop-bop-a-loom-a-boom-bam-boom")
} ?: run {
    println("null")
    println("When things go null, don't go with them")
}

1
mengapa Anda tidak menggunakan ifuntuk pemeriksaan nol? a?.let{} ?: run{}hanya sesuai dalam kasus yang jarang terjadi, jika tidak maka tidak idiomatis
voddan

2
@voddan Saya tidak menyarankan untuk tidak menggunakan jika untuk nullpemeriksaan, saya mencantumkan opsi lain yang layak. Meskipun saya tidak yakin apakah runmemiliki semacam penalti kinerja. Saya akan memperbarui jawaban saya untuk membuatnya lebih jelas.
Benito Bertoli

1
@voddan Jika aadalah a var, maka gunakan a?.let{} ?: run{}jaminan bahwa itu akan terikat dengan benar di letuntuk seluruh ruang lingkup. Jika aa val, maka tidak ada perbedaan.
dibuat

1
@madeinqc jika a val, maka menggunakan let berbeda dan itu buruk. Saya menemukan artikel ini sangat bagus dalam menjelaskannya - Kotlin: Jangan hanya menggunakan LET untuk pemeriksaan null .
Sufian

40

Cara Kotlin menangani null

Operasi Akses Aman

val dialog : Dialog? = Dialog()
dialog?.dismiss()  // if the dialog will be null,the dismiss call will be omitted

Biarkan berfungsi

user?.let {
  //Work with non-null user
  handleNonNullUser(user)
}

Keluar lebih awal

fun handleUser(user : User?) {
  user ?: return //exit the function if user is null
  //Now the compiler knows user is non-null
}

Bayangan yang tidak bisa diubah

var user : User? = null

fun handleUser() {
  val user = user ?: return //Return if null, otherwise create immutable shadow
  //Work with a local, non-null variable named user
}

Nilai default

fun getUserName(): String {
 //If our nullable reference is not null, use it, otherwise use non-null value 
 return userName ?: "Anonymous"
}

Gunakan val, bukan var

valbersifat read-only, varbisa berubah. Direkomendasikan untuk menggunakan sebanyak mungkin properti hanya-baca, properti ini aman untuk thread.

Gunakan lateinit

Terkadang Anda tidak dapat menggunakan properti yang tidak dapat diubah. Misalnya, ini terjadi di Android ketika beberapa properti diinisialisasi dalam onCreate()panggilan. Untuk situasi ini, Kotlin memiliki fitur bahasa yang disebut lateinit.

private lateinit var mAdapter: RecyclerAdapter<Transaction>

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   mAdapter = RecyclerAdapter(R.layout.item_transaction)
}

fun updateTransactions() {
   mAdapter.notifyDataSetChanged()
}

Saya akan menyebut yang terakhir sebagai "nilai default" (bukan elvis), karena 3/4 di antaranya menggunakan elvis.
AjahnCharles

@AjahnCharles masuk akal))
Levon Petrosyan

1
ini sampah, bahasa modern apa pun dapat menangani lebih baik dengan pilihan daripada ini. itu lebih merupakan tugas daripada manfaat bagi programmer.
JBarros35

10

Selain @Benito Bertoli,

kombinasinya sebenarnya tidak seperti if-else

"test" ?. let {
    println ( "1. it=$it" )
} ?: let {
    println ( "2. it is null!" )
}

Hasilnya adalah:

1. it=test

Tapi jika:

"test" ?. let {
    println ( "1. it=$it" )
    null // finally returns null
} ?: let {
    println ( "2. it is null!" )
}

Hasilnya adalah:

1. it=test
2. it is null!

Juga, jika menggunakan elvis dulu:

null ?: let {
    println ( "1. it is null!" )
} ?. let {
    println ( "2. it=$it" )
}

Hasilnya adalah:

1. it is null!
2. it=kotlin.Unit

5

Lihat metode yang berguna, ini bisa berguna:

/**
 * Performs [R] when [T] is not null. Block [R] will have context of [T]
 */
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
    return input?.let(callback)
}

/**
 * Checking if [T] is not `null` and if its function completes or satisfies to some condition.
 */
inline fun <T: Any> T?.isNotNullAndSatisfies(check: T.() -> Boolean?): Boolean{
    return ifNotNull(this) { it.run(check) } ?: false
}

Di bawah ini adalah contoh yang mungkin bagaimana menggunakan fungsi tersebut:

var s: String? = null

// ...

if (s.isNotNullAndSatisfies{ isEmpty() }{
   // do something
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.