Soll ich doppelt =
oder dreifach verwenden =
?
if(a === null) {
//do something
}
oder
if(a == null) {
//do something
}
Ähnliches gilt für "nicht gleich":
if(a !== null) {
//do something
}
oder
if(a != null) {
//do something
}
Soll ich doppelt =
oder dreifach verwenden =
?
if(a === null) {
//do something
}
oder
if(a == null) {
//do something
}
Ähnliches gilt für "nicht gleich":
if(a !== null) {
//do something
}
oder
if(a != null) {
//do something
}
Antworten:
Beide Ansätze generieren denselben Bytecode, sodass Sie auswählen können, was Sie bevorzugen.
Eine strukturelle Gleichheit a == b
wird übersetzt in
a?.equals(b) ?: (b === null)
Im Vergleich zu null
wird daher die strukturelle Gleichheit a == null
in eine referentielle Gleichheit übersetzt a === null
.
Laut den Dokumenten macht es keinen Sinn, Ihren Code zu optimieren. Sie können also Folgendes verwenden a == null
und a != null
beachten : Wenn die Variable eine veränderbare Eigenschaft ist, können Sie sie nicht intelligent in den nicht nullbaren Typ innerhalb der if
Anweisung umwandeln (weil Der Wert wurde möglicherweise von einem anderen Thread geändert let
. Stattdessen müssen Sie den Operator für sichere Anrufe verwenden.
Sicherer Anrufbetreiber ?.
a?.let {
// not null do something
println(it)
println("not null")
}
Sie können es in Kombination mit dem Elvis-Operator verwenden.
Elvis-Operator ?:
(Ich vermute, weil das Verhörzeichen wie Elvis 'Haare aussieht)
a ?: println("null")
Und wenn Sie einen Codeblock ausführen möchten
a ?: run {
println("null")
println("The King has left the building")
}
Die beiden kombinieren
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")
}
if
für Nullprüfungen? a?.let{} ?: run{}
ist nur in seltenen Fällen angebracht, sonst ist es nicht idiomatisch
null
Überprüfungen, ich habe andere praktikable Optionen aufgelistet . Obwohl ich nicht sicher bin, ob run
es irgendeine Art von Leistungsstrafe gibt. Ich werde meine Antwort aktualisieren, um es klarer zu machen.
a
ist ein var
, dann mit der a?.let{} ?: run{}
Garantie, dass es in der let
für den gesamten Umfang richtig gebunden wird . Wenn a a
ist val
, gibt es keinen Unterschied.
val
, dann ist die Verwendung von let anders und es ist schlecht. Ich fand diesen Artikel sehr gut darin, ihn zu erklären - Kotlin: Verwenden Sie LET nicht nur für die Nullprüfung .
Sicherer Zugriff
val dialog : Dialog? = Dialog()
dialog?.dismiss() // if the dialog will be null,the dismiss call will be omitted
Funktionieren lassen
user?.let {
//Work with non-null user
handleNonNullUser(user)
}
Vorzeitiger Ausstieg
fun handleUser(user : User?) {
user ?: return //exit the function if user is null
//Now the compiler knows user is non-null
}
Unveränderliche Schatten
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
}
Standardwert
fun getUserName(): String {
//If our nullable reference is not null, use it, otherwise use non-null value
return userName ?: "Anonymous"
}
Verwenden Sie val anstelle von var
val
ist schreibgeschützt, var
ist veränderlich. Es wird empfohlen, so viele schreibgeschützte Eigenschaften wie möglich zu verwenden. Sie sind threadsicher.
Verwenden Sie lateinit
Manchmal können Sie keine unveränderlichen Eigenschaften verwenden. Dies geschieht beispielsweise unter Android, wenn eine Eigenschaft beim onCreate()
Aufruf initialisiert wird . Für diese Situationen verfügt Kotlin über eine Sprachfunktion namens 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()
}
Ergänzung zu @Benito Bertoli,
Die Kombination ist eigentlich anders als wenn-sonst
"test" ?. let {
println ( "1. it=$it" )
} ?: let {
println ( "2. it is null!" )
}
Das Ergebnis ist:
1. it=test
Aber falls:
"test" ?. let {
println ( "1. it=$it" )
null // finally returns null
} ?: let {
println ( "2. it is null!" )
}
Das Ergebnis ist:
1. it=test
2. it is null!
Wenn Sie zuerst elvis verwenden:
null ?: let {
println ( "1. it is null!" )
} ?. let {
println ( "2. it=$it" )
}
Das Ergebnis ist:
1. it is null!
2. it=kotlin.Unit
Schauen Sie sich nützliche Methoden an, es könnte nützlich sein:
/**
* 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
}
Nachfolgend finden Sie ein mögliches Beispiel für die Verwendung dieser Funktionen:
var s: String? = null
// ...
if (s.isNotNullAndSatisfies{ isEmpty() }{
// do something
}