Nie mogę dowiedzieć się, co ?:robi na przykład w tym przypadku
val list = mutableList ?: mutableListOf()
i dlaczego można go zmodyfikować do tego
val list = if (mutableList != null) mutableList else mutableListOf()
Nie mogę dowiedzieć się, co ?:robi na przykład w tym przypadku
val list = mutableList ?: mutableListOf()
i dlaczego można go zmodyfikować do tego
val list = if (mutableList != null) mutableList else mutableListOf()
Odpowiedzi:
TL; DR: Jeśli wynikowe odwołanie do obiektu [pierwszy operand] nie jest null, jest zwracane. W przeciwnym razie zwracana jest wartość drugiego operandu (który może być null). Ponadto operator może zgłosić wyjątek, jeśli zostanie zwrócona wartość null.
Operator Elvis jest częścią wielu językach programowania, np Kotlin ale także Groovy lub C #. Uważam, że definicja z Wikipedii jest całkiem dokładna:
W niektórych językach programowania komputerowego operator Elvisa
?:jest operatorem binarnym, który zwraca swój pierwszy operand, jeśli tym operandem jesttrue, aw przeciwnym razie oblicza i zwraca drugi operand. Jest to wariant potrójnego operatora warunkowego ,? :, znalezionych w tych językach (i wielu innych): operator Elvis jest trójskładnikowych operatora z drugim argumencie pominięte .
Poniższe jest szczególnie prawdziwe w przypadku Kotlina:
Niektóre języki programowania komputerów mają inną semantykę dla tego operatora. Zamiast pierwszego operandu, który musi skutkować wartością logiczną, musi skutkować odwołaniem do obiektu . Jeśli wynikowe odwołanie do obiektu nie jest
null, jest zwracane. W przeciwnym razie zwracana jest wartość drugiego operandu (który może byćnull). Jeśli drugi operand ma wartość null, operator może również zgłosić wyjątek.
Przykład:
x ?: y // yields `x` if `x` is not null, `y` otherwise.
x ?: throw SomeException() // yields `x` if `x` is not null, throws SomeException otherwise
elvis operatormożna jeszcze bardziej zredukować do czegoś innego. miły! I miłe wyjaśnienie, dziękuję!
Elvis Operator reprezentowany jest przez znak zapytania a następnie dwukropek: ?:i może być używany z tej składni:
first operand ?: second operand
Umożliwia pisanie kodu konsensusowego i działa tak:
Jeśli first operand nie jest null , zostanie zwrócona. Jeśli jest zerowa , second operandzostanie zwrócona. Może to służyć do zagwarantowania, że wyrażenie nie zwróci wartości null, ponieważ podasz wartość niepodlegającą wartości null, jeśli podana wartość jest równa null.
Na przykład (w Kotlinie):
fun retrieveString(): String { //Notice that this type isn't nullable
val nullableVariable: String? = getPotentialNull() //This variable may be null
return nullableVariable ?: "Secondary Not-Null String"
}
W tym przypadku, jeśli obliczona wartość getPotentialNullnie jest zerowa, zostanie zwrócona przez retrieveString; Jeśli ma wartość null, "Secondary Not-Null String"zamiast tego zostanie zwrócone drugie wyrażenie .
Należy również zauważyć, że wyrażenie po prawej stronie jest oceniane tylko wtedy, gdy po lewej stronie jest null .
W Kotlinie możesz użyć dowolnego wyrażenia jako second operand, takiego jak throw Exceptionwyrażenie
return nullVariable ?: throw IllegalResponseException("My inner function returned null! Oh no!")
Nazwa Elvis Operator pochodzi od słynnego amerykańskiego piosenkarza Elvisa Presleya . Jego fryzura przypomina znak zapytania
Źródło: Wojda, I. Moskala, M. Android Development z Kotlin. 2017. Packt Publishing
Nazywa się to operatorem Elvisa i robi ... Dokładnie to, co opisałeś w swoim pytaniu. Jeśli jego lewa strona jest nullwartością, zwraca zamiast tego prawą stronę, jako rezerwę. W przeciwnym razie zwraca tylko wartość po lewej stronie.
a ?: bjest po prostu skrótem if (a != null) a else b.
Więcej przykładów z typami:
val x: String? = "foo"
val y: String = x ?: "bar" // "foo", because x was non-null
val a: String? = null
val b: String = a ?: "bar" // "bar", because a was null
a != null ? a : b
Spójrzmy na definicję :
Kiedy mamy odwołanie r dopuszczające wartość null, możemy powiedzieć „jeśli r nie jest null, użyj go, w przeciwnym razie użyj wartości x niezerowej”:
Operator ?:(Elvis) unika szczegółowości i sprawia, że kod jest naprawdę zwięzły.
Na przykład wiele funkcji rozszerzających kolekcję zwraca nulljako rezerwę.
listOf(1, 2, 3).firstOrNull { it == 4 } ?: throw IllegalStateException("Ups")
?:daje sposób na obsługę przypadku awaryjnego, nawet jeśli masz wiele warstw rezerwy. Jeśli tak, możesz po prostu połączyć w łańcuch multi operatorów Elvisa, jak tutaj:
val l = listOf(1, 2, 3)
val x = l.firstOrNull { it == 4 } ?: l.firstOrNull { it == 5 } ?: throw IllegalStateException("Ups")
Jeśli wyrazisz to samo za pomocą if else, będzie to dużo więcej kodu, który jest trudniejszy do odczytania.
Po prostu możemy powiedzieć, że masz dwie ręce. Chcesz wiedzieć, czy twoja lewa ręka pracuje teraz? Jeżeli lewa ręka nie działa, return emptyinnybusy
Przykład dla Java:
private int a;
if(a != null){
println("a is not null, Value is: "+a)
}
else{
println("a is null")
}
Przykład dla Kotlina:
val a : Int = 5
val l : Int = if (a != null) a.length else "a is null"
Operator elvis w Kotlin służy do zerowego bezpieczeństwa.
x = a ?: b
W powyższym kodzie xzostanie przypisana wartość, ajeśli a nie jest nulli bjeśli ajest null.
Odpowiedni kod kotlin bez użycia operatora elvis jest poniżej:
x = if(a == null) b else a