Kihagyás

Kotlin alapú szoftverfejlesztés - 4. előadás

Letöltés PDF-ként

Null-ok

class Person(val name: String)
fun main() {
    val person: Person = null //ilyet nem tudok, mert a Person-ba nem fér a null!
    val person2: Person? = null //nullable típus, azaz ez Person vagy null is lehet!
    println(person.name) //így nem tudunk akármilyen függvényhívást!

    if(person != null) {
        println(person.name) //kaptunk egy smart cast-ot, mert a feltétel bizonyítja, hogy nem null
    }

    person?.name //safe call operátor
        //ha a bal oldalán null van, kihagyja a hívást, és null-lesz az egész értéke
        //ha bal oldalt helyes érték van, akkor meghívódik a függvény
    val name: String? = person?.name //példa a használatára

    println(person?.company?.address?.building) //így lehet láncolni ezt
}
  • Elvis operator (?:), null coalescing operator
fun main() {
    val message: String? = readLine()
    val length = message?.length ?: 0 //ha a message null, akkor 0-t ad vissza
}
//egy még szebb megoldás:
fun processInput() {
    while(true) {
        val input: String = readLine() ?: return
        println("Read ${input.length} characters from input")
    }
}
  • null safety kikapcsolása (!!)

    val persin: Person? = Person("Jim")
    println(person!!.name) //a !! leszedi a kérdőjelt, ha meg null, dob egy null pointer exception-t!
    
  • safe cast (as?)

    for(entity in entities) {
        (entity as? Renderable)?.render(canvas) //ha nem felelt meg a típus tesztnek, akkor null lesz az (entity as? Renderable) rész
    }
    
  • lateinit → ha valamit csak később akarunk majd inicializálni

    private lateinit var timer: AnimationTimer
    //innentől ki van kapcsolva a null safety-ség
    //ha inicializálás előtt akarjuk használni, akkor errort kapunk!
    
  • platform type (String!) → Java-val való interakciókor jönnek létre

    • nem tudjuk, hogy lehet e null vagy sem
    • segíthetnek még az annotációk (@Nullable, @NotNull)
      • nehézség, hogy max a fejlesztőkörnyezet szól nekünk ha ezt megszegjük Javaban
      • Kotlin oldalról így már nem kell tippelnünk, hogy nullable vagy notnull a cucc
  • Java-bol Kotlin-ba híváskor Java nem ismeri a nullable és notnull dolgokat

    • megjelenik egy checkNotNull

Funkcionális programozás

  • alapelvek

    • függvények elsőrendű tagjai a nyelvnek (azaz nem csak osztály részeként lehet függvény)
    • pure függvények → csak az inputjaik alapján visszaadnak valamit (mástól nem függenek)
    • inkább val-okat használjuk → kevés olyan változónk van, aminek megváltozhat az értéke
    • imperatív helyett dekleratívan programozunk
      • nem a folyamatot írjuk le, hanem hogy mit akarunk megkapni
  • függvények rendezése

    • pl package-eken belül
    • megadhatjuk, hogy Java kódból milyen osztályból érhessük el ezeket
    @file:JvmName("TextUtils") //ezzel az annotációval megadható, hogy milyen osztályba legyenek becsomagolva ezek a függvények (az egész file-t becsomagolja)
    package util
    val LOWERCASE_ALPHABET = "abcdefghijklmnopqrstuvxyz"
    fun isEmpty(str: String?): Boolean {
        return str == null || str.lenght == 0
    }
    
    //random .java file:
    import util.TextUtils;
    class Main {
        public statis void main(String[] args) {
            TextUtils.isEmpty("is emptry?");
        }
    }
    
  • extensions → szép utility függvények

    • meglévő típus kibővítése új metódusokkal

      fun String.lastChar(): Char {
          return this[this.length - 1]
      }
      fun main() {
          println("Steve".lastChar())
      }
      
    • fontos hibalehetőség: extension-nel nem nagyon megy a polimorfizmus!

      abstract class Animal
      fun Animal.identify() {
          println("This is an animal")
      }
      class Cat: Animal()
      fun Cat.identify() {
          println("This is a cat!")
      }
      fun main() {
          val animal: Animal = Cat()
          animal.identify() // This is an animal-t fog kiírni!
      }
      
      • fordítási időben kellene eldönteni, hogy melyik függvény legyen meghívva, akkor azonban nem feltétlenül tudjuk (a polimorfizmusnak pont ez a lényege)