Lambdas - Data class - Smart cast - Null safety - Lazy property - Default values for function parameters - Extension Functions - No more ; - Single-expression functions - When expression - let, apply, use, with - Collections - Android Extensions Plugin
typing and null-safety make a big difference. "Some people say Kotlin has 80% the power of Scala, with 20% of the features" * "Kotlin is a software engineering language in contrast to Scala which is a computing science language." * Swift and Kotlin are VERY similar. Swift is LLVM based and has C interop while Kotlin is JVM based and has Java interop. * Quotes from Kotlin: The Ying and Yang of Programming Languages @ sdeleuze
-Dfile.encoding=UTF-8 org.gradle.parallel=true org.gradle.deamon=true # Kotlin kotlin.incremental=true # Android Studio 2.2+ android.enableBuildCache=true In your gradle.properties https://medium.com/keepsafe-engineering/kotlin-vs-java-compilation-speed-e6c174b39b5d#.k44v7axsk
= 1 // `Int` type is inferred var x = 5 // `Int` type is inferred x += 1 Inferred values Mutable values val : constant value - IMMUTABLE var : variable value - MUTABLE USE VAL AS MUCH AS POSSIBLE !
null //Compilation error - stringA is a String (non optional) var stringB: String? = "bar" // stringB is an Optional String stringB = null //ok Optional value with ?
(stringB != null) stringB.length else -1 //or with the Elvis operator val length = stringB?.length ?: -1 Default Value & Elvis Operator :? val length = stringB.length // Compilation error - stringB can be null ! // use ? the safe call operator val length = stringB?.length //Value or null - length is type Int? val length = stringB!!.length // Value or explicit throw NPE - length is type Int Safe call with ?. or Explicit call with !!.
== 0 Properties can be declared in constructor or in class You can also handle getter & setter lateinit var weatherWS : WeatherWS @Test fun testMyWeatherWS() { weatherWS = Inject.get<WeatherWS>() // ... } class ApiKey(var weatherKey: String, var geocodeKey: String){ var debug : Boolean = false } Late & Lazy initialization
-> print("x == 2") else -> { // Note the block print("x is neither 1 nor 2") } } Flow Control (replace your switch and if-blocks) when (x) { in 1..10 -> print("x is in the range") in validNumbers -> print("x is valid") !in 10..20 -> print("x is outside the range") else -> print("none of the above") } Pattern Matching
"b" to 2, "c" to 3) for ((k, v) in map) { println("$k -> $v") } map["a"] = "my value" // direct map access with array style // range for (i in 1..100) { //... } // immutable list val list = listOf("a", "b", "c","aa") list.filter { it.startsWith("a") } * collections operators : map, filter, take, flatMap, forEach, firstOrNull, last …
-> popLocationDialog(view) } A lambda expression or an anonymous function is a “function literal”, i.e. a function that is not declared, but passed immediately as an expression - A lambda expression is always surrounded by curly braces - Its parameters (if any) are declared before -> (parameter types may be omitted), - The body goes after -> (when present). myNumber.split("\n").flatMap { it.split(separator) } .map(Integer::parseInt) .map(::checkPositiveNumber) .filter { it <= 1000 } .sum() * Method references are not surrounded by curly braces !
value) -> "$value!" } Destructured variables declaration val person = Person("john",31) //data class Person(val name:String, val age : Int) val (name,age) = person println("I'm $name, my age is $age") * Works with Map, Data Class, Pair, Triple … => you can return 2 values in function !
// … } } fun WhatIsyourAge(user : User){ println("Your age is ${user.age}") } data class User (val name: String, val age : Int){ companion object{ fun sayHello(user : User){ //… } } } User u = new User("toto",42); User.Companion.sayHello(u); UserUtilsKt.WhatIsyourAge(u); UserSingleton.INSTANCE.stringify(u)
Great learning curve - Good doc & tools support - Don’t use anymore Butterknife, Dagger … - T_T hard to come back to Java https://www.ekito.fr/people/kotlin-in-production-one-year-later/