Odpowiedzi:
Możesz użyć let
tej 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ę run
funkcję tylko wtedy, gdy potrzebujesz bloku kodu. Możesz usunąć run
-block, jeśli masz tylko oneliner po elvis-operator ( ?:
).
Należy pamiętać, że run
blok zostanie oceniony, jeśli b
ma wartość null lub jeśli wartość let
-block wynosi null
.
Z tego powodu zwykle potrzebujesz tylko if
wyrażenia.
val a = if (b == null) {
// ...
} else {
// ...
}
W takim przypadku else
-block zostanie oszacowany tylko wtedy, gdy b
nie jest null.
a
nie jest jeszcze zdefiniowana w zakresie let
i run
. Ale możesz uzyskać dostęp do wartości b
wewnątrz za let
pomocą niejawnego parametru it
. To chyba służy temu samemu celowi.
a
przed tymi blokami kodu. I a
można dostać się do środka.
a
? Jeśli tak b
, to it
służy dokładnie temu samemu celowi. Czy ponownie przypisuje a
z wynikiem val
-block?
it
z let
bloku. Wynik bloku let
lub run
zostanie 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ść then
różną od zera, wprowadź -block z symbolem a
powiązanym z nieopakowaną wartością. W przeciwnym razie wprowadźelse
blok.
Zwróć szczególną uwagę, że a
jest 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
}
let
zamiast also
oznacza, że run
blok zostanie wykonany za każdym razem, gdy let
blok 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-let
instrukcja) 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 Binding
dla if-let
instrukcji wygląda następująco:
if-let
Oś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-let
wypowiedzi 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 */
let
Funkcja 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-let
instrukcji 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-let
Oświadczenie w Swift jest proste i potężne. Sprawdza, czy występuje warunek i jeśli zostanie oszacowany jako fałszywy, else
wykonywana 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-let
wypowiedzi 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 name
nie 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"
}
let
robi, ale pytanie dotyczy else
strategii, która jest wykonywana, jeśli obiekt, na którym let
jest 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 }
}
a
nie można uzyskać dostępu do środkalet
irun
zablokować.