Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin and why you should love it #2

Kotlin and why you should love it #2

Slides of the talk we gave in Ennova

Roberto Orgiu

July 04, 2017
Tweet

More Decks by Roberto Orgiu

Other Decks in Technology

Transcript

  1. LAMBDAS WITH RECEIVERS The ability to call methods of a

    different object in the body of a lambda without any additional qualifiers — Kotlin in Action
  2. with fun alphabet(): String { val result = StringBuilder() for

    (letter in 'A'..'Z') { result.append(letter) } result.append("\nNow I know the alphabet!") return result.toString() }
  3. with fun alphabet(): String { val stringBuilder = StringBuilder() return

    with(stringBuilder) { for (letter in 'A'..'Z') { this.append(letter) } append("\nNow I know the alphabet!") this.toString() } }
  4. with fun alphabet() = with(StringBuilder()) { for (letter in 'A'..'Z')

    { append(letter) } append("\nNow I know the alphabet!") toString() }
  5. apply fun alphabet() = StringBuilder().apply { for (letter in 'A'..'Z')

    { append(letter) } append("\nNow I know the alphabet!") }.toString()
  6. with VS apply Declaration Return type with Function value of

    the lambda apply Extension method this
  7. with VS apply inline fun <T, R> with(receiver: T, block:

    T.() -> R): R = receiver.block() inline fun <T> T.apply(block: T.() -> Unit): T { block() return this }
  8. let VS run inline fun <T, R> T.run(block: T.() ->

    R): R = block() inline fun <T, R> T.let(block: (T) -> R): R = block(this)
  9. DESTRUCTURING DECLARATION val mickey = Person("Mickey", "Mouse") val (name, lastName)

    = mickey MEANS val name = mickey.component1() val lastName = mickey.component2()
  10. LOCAL FUNCTIONS Functions can be nested inside a containing function

    And they have access to all parameters and variables of the enclosing function
  11. SEALED CLASSES sealed class Expr data class Const(val number: Double)

    : Expr() data class Sum(val e1: Expr, val e2: Expr) : Expr() object NotANumber : Expr()
  12. SEALED CLASSES fun eval(expr: Expr): Double = when(expr) { is

    Const -> expr.number is Sum -> eval(expr.e1) + eval(expr.e2) NotANumber -> Double.NaN }
  13. COMPANION object class MyClass { companion object Factory { fun

    create(): MyClass = MyClass() } } val instance = MyClass.create()
  14. object init > object declarations are initialized lazily, when accessed

    for the first time > object expressions are executed (and initialized) immediately, where they are used > a companion object is initialized when the corresponding class is loaded (resolved), matching the semantics of a Java static initializer
  15. interface Base { fun print() } class BaseImpl(val x: Int)

    : Base { override fun print() { print(x) } }
  16. lazy - THIS... val lazyValue: String by lazy { println("computed!")

    "Hello" } println(lazyValue) println(lazyValue)
  17. Delegates.observable() - THIS ... class User { var name: String

    by Delegates.observable("<no name>") { prop, old, new -> println("$old -> $new") } } fun main(args: Array<String>) { val user = User() user.name = "first" user.name = "second" }
  18. map DELEGATE class User(map: Map<String, Any?>) { val name: String

    by map val age: Int by map } val user = User(mapOf( "name" to "John Doe", "age" to 25 ))
  19. COLLECTIONS: MUTABLE VS IMMUTABLE val list = listOf(1, 2, 3)

    //immutable list of ints val list = mutableListOf(1, 2, 3) //mutable list of ints
  20. COLLECTIONS: MUTABLE VS IMMUTABLE > Mutable: you can insert, update

    and remove > Default: you can only query (contains, get, indexOf...) > MutableList / List > MutableSet / Set > MutableMap / Map
  21. COLLECTIONS: IMMUTABILITY val list = listOf(1, 2, 3) val doubles

    = list.map { it * 2 } val pairs = list.filter { it % 2 == 0 } > doubles is a completely new list > The original list is never touched