Odpowiedzi:
Możesz użyć lettej funkcji w następujący sposób:
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
Pamiętaj, że musisz wywołać tę runfunkcję tylko wtedy, gdy potrzebujesz bloku kodu. Możesz usunąć run-block, jeśli masz tylko oneliner po elvis-operator ( ?:).
Należy pamiętać, że runblok zostanie oceniony, jeśli bma wartość null lub jeśli wartość let-block wynosi null.
Z tego powodu zwykle potrzebujesz tylko ifwyrażenia.
val a = if (b == null) {
// ...
} else {
// ...
}
W takim przypadku else-block zostanie oszacowany tylko wtedy, gdy bnie jest null.
anie jest jeszcze zdefiniowana w zakresie leti run. Ale możesz uzyskać dostęp do wartości bwewnątrz za letpomocą niejawnego parametru it. To chyba służy temu samemu celowi.
aprzed tymi blokami kodu. I amożna dostać się do środka.
a? Jeśli tak b, to itsłuży dokładnie temu samemu celowi. Czy ponownie przypisuje az wynikiem val-block?
itz letbloku. Wynik bloku letlub runzostanie przypisany do a. Wynikiem jest ostatnie wyrażenie w bloku. Używasz zadania po zakończeniu let / porun zakończeniu, tak jak w przypadku każdego innego normalnego zadania.
Najpierw upewnijmy się, że rozumiemy semantykę podanego idiomu Swift:
if let a = <expr> {
// then-block
}
else {
// else-block
}
Oznacza to: „jeśli <expr> wynik ma wartość thenróżną od zera, wprowadź -block z symbolem apowiązanym z nieopakowaną wartością. W przeciwnym razie wprowadźelse blok.
Zwróć szczególną uwagę, że ajest to związane tylko do then-bloku . W Kotlinie możesz to łatwo uzyskać dzwoniąc
<expr>?.also { a ->
// then-block
}
i możesz dodać plik else -block w ten sposób:
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
Powoduje to taką samą semantykę, jak w idiomie Swift.
Moja odpowiedź jest całkowicie kopiowana przez innych. Jednak nie mogę łatwo zrozumieć ich wypowiedzi. Więc myślę, że byłoby miło udzielić bardziej zrozumiałej odpowiedzi.
Szybko:
if let a = b.val {
//use "a" as unwrapped
}
else {
}
W Kotlinie:
b.val?.let{a ->
//use "a" as unwrapped
} ?: run{
//else case
}
letzamiast alsooznacza, że runblok zostanie wykonany za każdym razem, gdy letblok zwróci null, co nie jest tym, czego chcemy.
W przeciwieństwie do Swifta, nie trzeba rozpakowywać opcjonalnego przed użyciem go w Kotlinie. Moglibyśmy po prostu sprawdzić, czy wartość jest różna od null, a kompilator śledzi informacje o wykonanym sprawdzeniu i zezwala na użycie go jako rozpakowanego.
W Swift:
if let a = b.val {
//use "a" as unwrapped
} else {
}
W Kotlinie:
if b.val != null {
//use "b.val" as unwrapped
} else {
}
Więcej takich przypadków użycia można znaleźć w dokumentacji: (null-safety)
if let komunikat.Swift's Optional Binding(tak zwana if-letinstrukcja) służy do sprawdzenia, czy opcja opcjonalna zawiera wartość, a jeśli tak, do udostępnienia tej wartości jako tymczasowej stałej lub zmiennej. Tak więc instrukcja Optional Bindingdla if-letinstrukcji wygląda następująco:
if-letOświadczenie Swifta :
let b: Int? = 50
if let a = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
W Kotlinie, podobnie jak w Swift, aby uniknąć awarii spowodowanych próbą uzyskania dostępu do wartości null, gdy nie jest to oczekiwane, przewidziana jest specyficzna składnia (jak b.let { }w drugim przykładzie) do prawidłowego rozpakowania nullable types:
Kotlin odpowiednik 1
if-letwypowiedzi Swifta :
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 */
letFunkcja Kotlina , gdy jest używana w połączeniu z operatorem bezpiecznego wywołania ?:, zapewnia zwięzły sposób obsługi wyrażeń dopuszczających wartość null.
Kotlin odpowiednik 2 (funkcja let inline i operator Elvisa)
if-letinstrukcji 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 komunikat.guard-letOświadczenie w Swift jest proste i potężne. Sprawdza, czy występuje warunek i jeśli zostanie oszacowany jako fałszywy, elsewykonywana jest instrukcja, która normalnie kończy działanie metody.
Przyjrzyjmy się stwierdzeniu Swifta
guard-let:
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 */
Podobny efekt Kotlina
guard-letwypowiedzi Swifta :
W przeciwieństwie do Swifta, w Kotlinie nie ma żadnego oświadczenia strażnika . Możesz jednak użyć Elvis Operator-, ?:aby uzyskać podobny efekt.
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! */
Mam nadzieję że to pomoże.
Oto jak wykonać kod tylko wtedy, gdy namenie jest 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"
}
letrobi, ale pytanie dotyczy elsestrategii, która jest wykonywana, jeśli obiekt, na którym letjest wywoływany, jest null. Swift ma to w bardziej naturalny (dyskusyjny) sposób. Ale zrobiwszy dużo zarówno Kotlin, jak i Swift, chciałbym, aby Kotlin miał proste rozpakowanie, jak robi to Swift.
Oto mój wariant, ograniczony do bardzo powszechnego przypadku „jeśli nie zerowy”.
Przede wszystkim zdefiniuj to gdzieś:
inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
if (obj != null) {
block(obj)
}
}
Prawdopodobnie powinno internal , aby uniknąć konfliktów.
Teraz przekonwertuj ten kod Swift:
if let item = obj.item {
doSomething(item)
}
Do tego kodu Kotlin:
ifNotNull(obj.item) { item ->
doSomething(item)
}
Zauważ, że jak zawsze w przypadku bloków w Kotlinie, możesz porzucić argument i użyć it:
ifNotNull(obj.item) {
doSomething(it)
}
Ale jeśli blok ma więcej niż 1-2 wiersze, prawdopodobnie najlepiej jest to wyraźnie określić.
To jest tak podobne do Swift, jak mogłem znaleźć.
W kotlinie istnieje podobny sposób osiągnięcia stylu Swifta, jeśli - pozwolę
if (val a = b) {
a.doFirst()
a.doSecond()
}
Można również przypisać wiele wartości dopuszczających wartość null
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
Takie podejście będzie bardziej odpowiednie, jeśli wartości dopuszczające wartość null są używane więcej niż 1 razy. Moim zdaniem pomaga to z punktu widzenia wydajności, ponieważ wartość zerowa zostanie sprawdzona tylko raz.
źródło: Dyskusja Kotlin
Dodaję tę odpowiedź, aby wyjaśnić zaakceptowaną odpowiedź, ponieważ jest za duża na komentarz.
Ogólny wzorzec jest taki, że możesz użyć dowolnej kombinacji funkcji zakresu dostępnych w Kotlin oddzielonych operatorem Elvisa w następujący sposób:
<nullable>?.<scope function> {
// code if not null
} :? <scope function> {
// code if null
}
Na przykład:
val gradedStudent = student?.apply {
grade = newGrade
} :? with(newGrade) {
Student().apply { grade = newGrade }
}
anie można uzyskać dostępu do środkaletirunzablokować.