2012. október 17., szerda

Kotlin tesztkör

Néhány hónapja a Jetbrains orosz csapata bejelentette hogy új JVM nyelvet fejlesztenek Kotlin néven. Próbálgatom, gondoltam pár dolgot mesélek, hátha érdekes. Nem lesz teljes leírás, csak kedvcsináló. Ha megjött a kedved hozzá, látogass el a kotlin weboldalára! Türelmetleneknek a végén összefoglaló.

var vagy val


Meséltem neketek a beteges final-ozásomról. Nos a magamfajta elvetemülteknek alighanem üdítő feature a kotlin nyelvben az, hogy a változó deklarációjánál meg kell mondani, hogy változhat-e vagy sem. Ami változhat, az var (variable), ami nem, az val (value).
Ez semmi új, a scala is hasonló koncepcióval jött.

A változók deklarációjánál még tréfi az is, hogy nem kell kétszer elmondanod a típust. Kitalálja. Példa:

val kakukk = "kakukk" //nyilván string
val map = HashMap<String, String>()

Azt gondolom észrevetted, hogy new sincs. Nincsen. Mondjuk a melóhelyi projectemen, hogy a metódusok fele nagybetűvel kezdődik többnyire nem érteném, hogy ez most új objektum vagy csak hívás... desebaj, az úgyse nem lesz kotlinban.

Mr Bean


Természetesen property-k definiálása is kapott egy szebb és kompaktabb szintaxist. Elösször is, minden amit var-ként definiál az ember, az egyből property, getterrel, setterrel, tokkal vonóval.

var name : String? = null;

Ennyi, ha nem akarod felüldefiniálni a getter tartalmát. Nagyon ajánlanám, hogy ne akard, vicces dolgokat lehet vele elkövetni. Pl ha a getterből a property-re hivatkozol, akkor simán a kód meghívja önmagát. Ezt gondolom majd kijavítják :)

Null-safety


A null értékektől való para mindig is itt volt, mióta java platform létezik, meg még elötte is, csak szegény emberek elötte egy segmentaiton fault-ot kaptak, nem pedig NPE-t. Azért ha a kettő közül kell választani, akkor én még mindig inkáb a NPE-t választanám, az nem feltétlenül halálos.
Míg a java nyelv esetében erőtlen próbálkozásokat látunk annotációk bevezetésére, az új JRE nyelvek mind valamilyen mehanizmussal jönnek a null értékek kezelésére. A kotlin megkülönbözteti tipusonként, hogy lehet-e null. Például egy funkció, ami esetleg null-t ad vissza, azt így deklarálod:

fun talánNull() : String?

Na ez nagyon kedves, de a sima java-ban nincs ilyen, ezért minden java API minden visszaadott értéke a kotlin szempontjából esetleg null lehet. Na most például a slf4j LoggerFactory.getLogger(akármi.class) soha nem ad vissza null értéket, de a kotlin ezt nem érti, viszont néhány kényelmes operátort ad az esetleges null-támadás kivédésére. Az egyik a !! operátor. Ez a "Hidd el nekem hogy nem null, dögöljek meg itt azonnal ha null!!" operátor :) A log4j esetében például így nézne ki:

LoggerFactory.getLogger(akármi.class)!!

A másik lehetőség, az úgynevezett Elvis operátor. Elvis-szel azokat a helyzeteket tudod röviden megfogalmazni, amikor null értéket valami mással helyettesítenél. Pl ha getFoo() null-t ad vissza, akkor helyettesítsük le inkáb foo-ra:

val foo : String = getFoo() ?: "foo";

Ez a (x == null) ? null : x.getFoo() típusú műveletekre használatos. Így néz ki a fenti példa esetében fél szemű Elvis-szel.

x?.getFoo()

Ez null lesz, ha x null, és a getFoo() értéke, ha x nem null. Egész kompakt.

Nincs static


Ez a dolog nekem már scala-ban is nehezen esett le, de nincsen statikus változó. Első felmerülő kérdés egyből az, hogy akkor hogy a túróba fogok loggert deklarálni. Valahogy így

class object {
    private val logger : Logger = LoggerFactory.getLogger(akármi.class)!!
}

Innetől ugyanúgy használhatod, mintha egy sima statikus logger lenne.

Closure


Minden új JVM nyelv lehetőséget ad closure-ök használatára (különben az érdeklődés hiányával kell szembenéznie), a kotlin sem kivétel. Nézzünk egy gyors példát:

fun kickntimes(int cnt, fn : () - > Unit) {
   for(i in 0 .. cnt) {
      fn();
   }
}
...

kickntimes(100, {print("bla")});

Extension functions


Ez sem új, a groovy is és a scala is mindenféle extrákkal cicomázza fel a java osztályait. Így lesz a java.io.File osztálynak olyan metódusa, aminek például átpasszolsz egy closure-t és minden sorára meghívja. Valahogy így:

val myFile = File("bla");
myFile.forEachLine({ print(it); });

IDE


Mivel Jetbrains, nyilván idea plugin van hozzá. Azért annyira sokat azért ne várj tőle, épp úgy fejlesztés alatt áll, mint a nyelv maga. Szinez, pár helyen kisegíti a szintaxist, kódformáz. Refaktorálni többnyire nem tud, csak az alapokat (osztály átnevezés).

Összevisszafoglaló


Szóval egészen sok új dolga van a kotlinnak, érdekes koncepciók vannak benne és van. (Ellenben a scala IDE mindig elavult eclipse-re epül, amellett hogy nem is tud sokat) kotlint használni kicsit olyan érzés, mintha délután négykor érkeznél a házibuliba: nagyon korai. Majd meglátjuk mi sül ki belőle.