Kotlin'de kontrol etmenin en iyi yolu?


Yanıtlar:


63

Her iki yaklaşım da aynı bayt kodunu üretir, böylece tercih ettiğiniz şeyi seçebilirsiniz.


4
. İ doğru anlasalardı o zaman değil hangi yaklaşımın iyi bayt kod oluşturur, KOTLIN onay boş en iyi şekilde istiyor @ BenitoBertoli cevap görünüyor umut verici, bu kadar Demirbaş kodu azaltır
IMGS

156

Yapısal bir eşitlik a == b,

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

Bu nedenle, ile kıyaslandığında null, yapısal eşitlik a == nullreferans eşitliğine çevrilir a === null.

Dokümanlara göre , kodunuzu optimize etmenin bir anlamı yoktur, bu nedenle kullanabilirsiniz a == nullve a != null


Unutmayın ki değişken değiştirilebilir bir özellik ise, ififadenin içindeki boş değer atanamaz tipine akıllıca çeviremezsiniz (çünkü değer başka bir iş parçacığı tarafından değiştirilmiş olabilir) ve letbunun yerine güvenli çağrı operatörünü kullanmanız gerekir.

Güvenli arama operatörü ?.

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


Elvis operatörü ile birlikte kullanabilirsiniz.

Elvis operatörü ?: (tahmin ediyorum çünkü sorgulama işareti Elvis'in saçına benziyor)

a ?: println("null")

Ve bir kod bloğu çalıştırmak istiyorsanız

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

İkisini birleştirmek

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
neden ifboş kontroller için kullanmıyorsun ? a?.let{} ?: run{}yalnızca nadir durumlarda uygundur, aksi takdirde deyimsel değildir
voddan

2
@voddan nullÇekler için eğer kullanmamayı önermiyordum , diğer geçerli seçenekleri listeliyordum. Yine runde bir tür performans cezası olup olmadığından emin değilim . Daha net hale getirmek için cevabımı güncelleyeceğim.
Benito Bertoli

1
@voddan Eğer abir olduğunu varo zaman kullanarak, a?.let{} ?: run{}o düzgün bağlanmış olacağını garanti letbütün kapsam için. Eğer aa ise val, o zaman fark yoktur.
madeinqc

1
@madeinqc eğer a bir ise val, let kullanmak farklıdır ve kötüdür. Bu makaleyi açıklamada çok iyi buldum - Kotlin: Boş kontrol için LET'i sadece kullanmayın .
Sufian

40

Kotlin null işleme yolları

Güvenli Erişim İşlemi

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

Let işlevi

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

Erken çıkış

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

Değişmez gölgeler

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
}

Varsayılan değer

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

Var yerine val kullanın

val salt okunurdur, var değiştirilebilir. Mümkün olduğu kadar çok salt okunur özellik kullanmanız önerilir, bunlar iş parçacığı açısından güvenlidir.

Lateinit kullan

Bazen değişmez özellikleri kullanamazsınız. Örneğin, onCreate()çağrıda bazı özellikler başlatıldığında Android'de olur . Bu durumlar için Kotlin adında bir dil özelliğine sahiptir 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()
}

Sonuncusuna "varsayılan değer" (elvis değil) derdim, çünkü bunların 3 / 4'ü elvis kullanıyor.
AjahnCharles

@AjahnCharles anlamda)) yapar
Levon Ter-Petrosyan

1
bu saçmalık, modern herhangi bir dil isteğe bağlı seçeneklerle bundan daha iyi başa çıkabilir. bu, programcılar için bir avantajdan çok bir angarya.
JBarros35

10

@Benito Bertoli'ye ek,

kombinasyon aslında if-else'ten farklıdır

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

Sonuç:

1. it=test

Ama eğer:

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

Sonuç:

1. it=test
2. it is null!

Ayrıca, önce elvis kullanırsanız:

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

Sonuç:

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

5

Yararlı yöntemleri kontrol edin, yararlı olabilir:

/**
 * 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
}

Aşağıda bu işlevlerin nasıl kullanılacağına dair olası bir örnek verilmiştir:

var s: String? = null

// ...

if (s.isNotNullAndSatisfies{ isEmpty() }{
   // do something
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.