IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

6. diel - Typový systém: Null safety v Kotlin

V predchádzajúcom cvičení, Riešené úlohy k 5. lekcii Kotlin, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.

V minulej lekcii, Riešené úlohy k 5. lekcii Kotlin , sme sa naučili ušetriť si prácu pomocou cyklov. Teraz si konečne vysvetlíme koncept tzv. Null safety, ktorý je v Kotlin veľmi dôležitý a povieme si, čo znamenajú všetky tie výkričníky v zdrojovom kóde. S niekoľkými sme sa už stretli a hoci sa môže pre začiatok jednať o zložitejší koncept, tak bude lepšie, keď budeme aspoň tušiť, o čo sa jedná.

Koncept hodnoty null

Programovacie jazyky sa musí nejako vysporiadať so situáciou, kedy premenná nemá žiadnu hodnotu. S takýmto problémom sa často stretávame u funkcií, ktoré sa nemusia vykonať korektne. Ak sa napr. Nepodarí načítanie čísla z konzoly, nemalo by byť vrátený žiadne číslo, ale "prázdno". Ak by nám Kotlin vrátil v tomto prípade napr. Hodnotu 0 alebo -1, nepoznali by sme či sa číslo nepodarilo načítať alebo či používateľ vložil práve 0 alebo -1. Za týmto účelom sa vymyslela špeciálnu hodnotu null, ktorá bezpečne označí, že je premenná prázdna.

Pokiaľ si v Kotlin vytvoríme štandardnej premennú, prázdnu hodnotu null do nej priradiť nedá:

// Tento kód je nesprávny
var cislo = 15
cislo = null // Tento riadok vyvolá chybu

Niekto by ju tam totiž nemusel očakávať. Aby sme null mohli do premennej priradiť, musíme premennú najprv deklarovať ako nullovatelnou.

Nullovatelné typy

Nullovatelný typ môžeme chápať ako akýsi box, ktorý slúži na zabalenie obyčajné premenné. Box vždy existuje, po jeho otvorení ale hodnotu buď nájdeme, alebo je prázdny. Nullable typ vytvoríme tak, že za názov dátového typu premennej umiestnime otáznik ?. Skúsme si to:

var moznaCislo: Int? = 15
moznaCislo = null

Kód sa už preložil v poriadku a premenná moznaCislo je teraz prázdna, aj keď sa jedná o číslo. To znie zatiaľ dobre, že?

Je tu však problém, ktorý mnoho ostatných programovacích jazykov nedokázalo vyriešiť. S moznaCislo by nám teraz nemalo byť umožnené pracovať ako s obyčajnou premennou. Ak by sme napísali:

var moznaCislo: Int? = 15
moznaCislo = null
println(moznaCislo  * 2)

a program sa preložil, mohol by za behu spadnúť v prípade, že by moznaCislo bolo prázdne. Nemôžeme predsa vynásobiť "nezadané" dvoma. Keď si taký program skúsite napísať, zistíte, že nejde preložiť. Podobne by nám Kotlin vynadal aj pri prístupe k vlastnosti alebo metóde nullovatelného typu. Môžete si skúsiť, že kvôli výpisu dĺžky druhého reťazca nepôjde nasledujúci kód preložiť:

var s1 = "Ahoj"
var s2: String? = "Svete"
println(s1.length)
println(s2.length)

Asi ste tušili, že Kotlin nepatrí medzi jazyky, ktoré by si tento problém neohlídaly :)

Null safety

Mechanizmus, ktorý už pri preklade kontroluje ako nullovatelné typy používame, sa nazýva null safety. Existuje niekoľko spôsobov ako nullovatelnou premennú použiť. Postupne si ich vyskúšame.

Operátor !!

Začnime tým najhlúpejšom, ktorý sme zatiaľ v kurze používali, aby toho na nás nebolo zo začiatku moc. Pomocou operátora !! môžeme Kotlin degradovať na staršie jazyky ako je napr. Java a kontrolu null safety vypnúť. Ak v premennej zrovna nebude null, všetko bude fungovať:

var moznaCislo: Int? = 15
println(moznaCislo!!  * 2)

výsledok:

30

Ak v nej však prázdna hodnota bude, celá aplikácia za behu upadne s chybou:

var moznaCislo: Int? = 15
moznaCislo = null
println(moznaCislo!!  * 2)

Keďže pri preklade by sme na túto chybu vôbec neprišli, nebudeme riešenie s !! príliš používať.

Podmienka

O niečo múdrejší riešenia je pracovať s nullovatelnými typmi v podmienke na hodnotu null. Keďže sa tak vyhneme pádu programu, Kotlin nám program dovolí preložiť:

var moznaCislo: Int? = 15
if (moznaCislo != null)
    println(moznaCislo  * 2)
else
    println("Číslo nie je zadané!")

Bezpečné volanie

Určite tušíte, že existuje lepšie riešenie ako písať stále podmienky na null. Pomocou operátora ?. (otáznik bodka) sa buď pristúpi k danej vlastnosti alebo sa vráti null v prípade, že je premenná prázdna.

?.let

Ak by sme použili bezpečné volania spolu s kľúčovým slovom let, spustil by sa kód v zložených zátvorkách iba v prípade, že by v premennej bola ne-nullová hodnota:

var moznaCislo: Int? = 15
moznaCislo?.let { println(it) }

Kľúčové slovo it následne v bloku obsahuje túto hodnotu. Pokiaľ by bolo moznaCislo null, program by sa preložil a výpis by sa nespustil.

Reťazenie ?.

Túto funkcionalitu využijeme len v prípade, keď sa chceme opýtať cez reťaz vlastností ako napr .:

zak?.ucitel?.nadrizeny?.jmeno

Výraz vyššie vráti buď názov riaditeľa školy (nadriadeného učiteľa žiaka) alebo null v prípade, že je akýkoľvek článok výrazu prázdny. Ušetríme tak veľa podmienok, avšak musíme pamätať na to, že vo výsledku máme stále hoci jeden tak stále nullovatelný typ.

Mohli by sme takto aj bezpečne priradiť, už bez potreby ďalších podmienok:

zak?.ucitel?.nadrizeny?.jmeno = "Seymour Skinner"

Elvis operátor

Elvis operátor v Kotlin - Základné konštrukcie jazyka Kotlin

Ako vznikol názov tohto operátora asi netreba vysvetľovať :) Elvisa používame spolu s operátorom ?. a umožňuje nám opýtať sa, či je hodnota v nullovatelné premennej null a prípadne použiť inú predvolenú hodnotu. Opäť si to skúsme na našom príklade:

var moznaText: String? = "Ahoj svete"
println(moznaText?.length ?:  0)

Na pravej strane Elvis operátora môžeme použiť aj return alebo vyvolanie výnimiek (pozri ďalšie kurzy).

V každom zo spôsobov práce s hodnotou null platí, že ak je hodnota null, ďalšie výrazy (metódy) určené pre prípad keby null nebola sa nespustí.

V budúcej lekcii, Poľa v Kotlin , sa budeme venovať poliam.


 

Predchádzajúci článok
Riešené úlohy k 5. lekcii Kotlin
Všetky články v sekcii
Základné konštrukcie jazyka Kotlin
Preskočiť článok
(neodporúčame)
Poľa v Kotlin
Článok pre vás napísal Samuel Kodytek
Avatar
Užívateľské hodnotenie:
3 hlasov
Autor se věnuje všem jazykům okolo JVM. Rád pomáhá lidem, kteří se zajímají o programování. Věří, že všichni mají šanci se naučit programovat, jen je potřeba prorazit tu bariéru, který se říká lenost.
Aktivity