Szukaj…


Typy zerowalne i niepozwalające

Typy normalne, takie jak String , nie są zerowalne. Aby umożliwić im przechowywanie wartości zerowych, musisz to wyraźnie zaznaczyć, wstawiając znak ? za nimi: String?

var string        : String = "Hello World!"
var nullableString: String? = null

string = nullableString    // Compiler error: Can't assign nullable to non-nullable type.
nullableString = string    // This will work however!

Bezpieczny operator połączeń

Aby uzyskać dostęp do funkcji i właściwości typów zerowalnych, musisz użyć specjalnych operatorów.

Pierwszy ?. , daje właściwość lub funkcję, do której próbujesz uzyskać dostęp, lub daje wartość null, jeśli obiekt ma wartość null:

val string: String? = "Hello World!"
print(string.length)   // Compile error: Can't directly access property of nullable type.
print(string?.length)  // Will print the string's length, or "null" if the string is null.

Idiom: wywoływanie wielu metod na tym samym obiekcie o sprawdzonej wartości zerowej

Elegancki sposób, aby wywołać wiele metod null sprawdzane obiektu korzysta Kotlin jest apply tak:

obj?.apply { 
    foo()
    bar()
}

Wywoła to foo i bar na obj (co jest this w apply bloku) tylko wtedy, gdy obj jest niezerowe, omijając cały blok inaczej.

Aby wprowadzić zmienną zerowalną do zakresu jako odwołanie, które nie jest zerowalne, bez uczynienia z niej domyślnego odbiorcy wywołań funkcji i właściwości, możesz zastosować let zamiast apply :

nullable?.let { notnull ->
    notnull.foo()
    notnull.bar()
}

notnull może być nazwany jakikolwiek, a nawet pominięty i użyty przez niejawny parametr lambda it .

Inteligentne obsady

Jeśli kompilator może wywnioskować, że obiekt nie może być pusty w pewnym momencie, nie musisz już używać specjalnych operatorów:

var string: String? = "Hello!"
print(string.length)  // Compile error
if(string != null) {
    // The compiler now knows that string can't be null
    print(string.length)  // It works now!
}

Uwaga: Kompilator nie pozwala na inteligentne rzutowanie zmiennych, które można potencjalnie modyfikować między sprawdzaniem wartości zerowej a zamierzonym użyciem.

Jeśli zmienna jest dostępna spoza zakresu bieżącego bloku (ponieważ na przykład są członkami obiektu nielokalnego), musisz utworzyć nowe lokalne odwołanie, które możesz następnie inteligentnie rzutować i używać.

Wyeliminuj wartości zerowe z tablicy iterowalnej

Czasami musimy zmienić typ z Collection<T?> Na Collections<T> . W takim przypadku filterNotNull jest naszym rozwiązaniem.

val a: List<Int?> = listOf(1, 2, 3, null)
val b: List<Int> = a.filterNotNull()

Null Coalescing / Elvis Operator

Czasami pożądane jest, aby ocenić wyrażenie zerowalne w sposób „jeśli-inaczej”. Operator elvis, ?: , Może być użyty w Kotlinie w takiej sytuacji.

Na przykład:

val value: String = data?.first() ?: "Nothing here."

Powyższe wyrażenie zwraca "Nothing here" jeśli data?.first() lub same data dają wartość null , w przeciwnym razie wynik data?.first() .

Możliwe jest także zgłaszanie wyjątków przy użyciu tej samej składni, aby przerwać wykonywanie kodu.

val value: String = data?.second() 
    ?: throw IllegalArgumentException("Value can't be null!")

Przypomnienie: wyjątki NullPointerException mogą być zgłaszane za pomocą operatora asercji (np. data!!.second()!! Second data!!.second()!! )

Twierdzenie

!! sufiksy ignorują nullability i zwracają wersję tego typu inną niż null. KotlinNullPointerException zostanie KotlinNullPointerException , jeśli obiekt ma null .

val message: String? = null
println(message!!) //KotlinNullPointerException thrown, app crashes

Elvis Operator (? :)

W Kotlinie możemy zadeklarować zmienną, która może zawierać null reference . Załóżmy, że mamy odwołanie zerowe a , możemy powiedzieć „jeśli a nie jest zerowe, użyj go, w przeciwnym razie użyj wartości innej niż null x

var a: String? = "Nullable String Value"

Teraz może być null. a Kiedy więc potrzebujemy uzyskać dostęp do wartości a , musimy przeprowadzić kontrolę bezpieczeństwa, niezależnie od tego, czy zawiera ona wartość, czy nie. Możemy przeprowadzić tę kontrolę bezpieczeństwa za pomocą konwencjonalnej instrukcji if...else .

val b: Int = if (a != null) a.length else -1

Ale tu pojawia operator advance Elvis (Operator Elvis: ?: ). Powyżej, if...else operator może wyrazić za pomocą operatora Elvis, jak poniżej:

val b = a?.length ?: -1

Jeśli wyrażenie po lewej stronie ?: (Tutaj: a?.length ) nie jest puste, operator a?.length zwraca je, w przeciwnym razie zwraca wyrażenie po prawej stronie (tutaj: -1 ). Wyrażenie po prawej stronie jest oceniane tylko wtedy, gdy lewa strona jest pusta.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow