Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

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ť:

Klikni pre editáciu
  • var moznaCislo: Int? = 15
    println(moznaCislo!!  * 2)
    
    • Skontroluj, či výstupy programu zodpovedajú predlohe. S inými textami testy neprejdú.

    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ť:

    Klikni pre editáciu
    • var moznaCislo: Int? = 15
      if (moznaCislo != null)
          println(moznaCislo  * 2)
      else
          println("Číslo nie je zadané!")
      
      • Skontroluj, či výstupy programu zodpovedajú predlohe. S inými textami testy neprejdú.

      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:

      Klikni pre editáciu
      • var moznaCislo: Int? = 15
        moznaCislo?.let { println(it) }
        
        • Skontroluj, či výstupy programu zodpovedajú predlohe. S inými textami testy neprejdú.

        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:

        Klikni pre editáciu
        • var moznaText: String? = "Ahoj svete"
          println(moznaText?.length ?:  0)
          
          • Skontroluj, či výstupy programu zodpovedajú predlohe. S inými textami testy neprejdú.

          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.


           

          Ako sa ti páči článok?
          Pred uložením hodnotenia, popíš prosím autorovi, čo je zleZnakov 0 z 50-500
          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