Kotlin intro

Anton Rutkevich

JunoLab

About me

  • Android
  • Java, Kotlin, Groovy
  • Gradle, mobile CI

Who's out there? :)

Why Kotlin?

We need
safe & readable
code

Kotlin

  • Created by JetBrains
  • Announced in 2011
  • 1.0 release in Feb 2016
  • Latest - 1.0.1 (March 2016)

Easy to write safe code

Kotlin language
Libraries

Kotlin language

General

val / var, not null

// Constant
val a: Int = 1

// Variable
var b: Int = 2
b++

// Nullable variable
var c: String? = null
c?.charAt(0) // returns Char?

Functions

// Regular function
fun sum(a: Int, b: Int): Int {
    return a + b
}

// Same as above
fun sum(a: Int, b: Int) = a + b

// Default arguments
fun sumWithDefault(a: Int, b: Int = 10) 
    = a + b

Functions usage

val sum = sum(42, 42)

// Named arguments
val sum = sum(a = 42, b = 42)

// Omit default parameter
val sumWithDefault 
    = sumWithDefault(42) 

When

fun cases(obj: Any) {
    when (obj) {
        1          -> print("One")
        "Hello"    -> print("Greeting")
        is Long    -> print("Long")
        !is String -> print("Not a string")
        else       -> print("Unknown")
    }
}

return if / when / try

fun textColorRes(): Int {
    return if (isValid()) {
        R.color.green
    } else {
        R.color.red
    }
}

Ranges

if (errorCode in 400..499) {
    ...
}

for (x in 1..5) {
    ...
}

Smart casts: nulls

val a: String? = canReturnNull()

// Compile time error
val aLength = a.length

val aLength = if (a != null) {
    // 'a' is non-nullable here
    a.length 
} else {
    0
}

Smart casts: types

val any: Any = getAny()

val message: String = when(any) {
    is String -> any.capitalize()
    is Number -> "Number ${any}"
    is List<*> -> "List of size ${list.size()}"
}

Kotlin language

Classes

Constructors

class Cat

class Dog(val name: String)

class Mouse(name: String) {
    init {
        logger.info("Initialized with ${name}")
    }
}

Constructors 2

class MyView : View {
    constructor(ctx: Context) : super(ctx) { .. }

    constructor(ctx: Context, attrs: AttributeSet) 
       : super(ctx, attrs) { .. }
}

Properties

class Address { 
  var city: String = // ...
  
  var street: String
    get() = {
      // ...
    }
    set(value) {
      // ...
    }
}

Data classes

data class Customer(
    val id: String, val email: String
)

val customer = Customer("Ivan", "ivan@mail.ru")
val customerOneYearLater
   = customer.copy(email = "ivan@gmail.com")

Inheritance

open class Base {
    open fun canBeOverridden() {}
    fun notOverrideable() {}
}

class Derived() : Base() {
    override fun canBeOverridden() {}
}

Nested & Inner classes

class Outer {
  val bar = 1
  class Nested {
    // has no access to 'bar'
  }
}

class Outer {
  var bar = 1
  inner class Inner {
    // can access 'bar'
  }
}

Delegates

class MyActivity: Activity() {

    lateinit var loginButton: Button

    val userNameLabel: TextView by lazy {
        findViewById(R.id.user_name_label) as TextView
    }

    var userName: String by Delegates.observable("") { 
            metadata, old, new ->
        userNameLabel.setText(new)
    }
}

Extensions

fun Context.shortToast(text: String) {
    Toast.makeText(this, text, Toast.LENGTH_SHORT)
         .show()
}

class MainActivity: Activity() {
    override fun onStart() {
        super.onStart()
        shortToast("On Start")
    }
}

Kotlin language

Lambdas & Collections

Lambdas

class MainActivity: Activity(), SomeCallbackListener {
    var loginButton: Button = ...

    override fun onCreate(savedInstanceState: Bundle) {
        loginButton.setOnClickListener { 
            // do something
        }
    }

    override fun onJobDone(result: String) {
        runOnUiThread {
            // Modify UI on main thread
        }
    }
}

Collections

val list: List<String> = listOf("1", "2", "3")
list.add("4") // No such method :)


val mutableList: MutableList<String> 
    = listOf("4", "5", "6")

mutableList.add("7") // OK

Collections + lambdas !

val list = listOf("one", "two", "three")

list.filter { 
    it.length() < 5 
}.map { 
    it.reverse() 
}.forEach { 
    println("String: ${it}") 
}

Libraries

We use

RxJava

Dagger 2

Retrofit

Gson

and others

Rule of thumb

Java libraries work well with Kotlin

RxJava
 

works much better than in Java

Dagger 2

works

Retrofit

works

Gson

works, but is a bit dangerous

Statistics

Shut up and take my money method count

Library Size Method count
scala-library-2.11.7 5.7 Mb 50811
groovy-2.4.4 4.6 Mb 28768
kotlin-runtime-1.0.1 205 Kb 902
kotlin-stdlib-1.0.1 624 Kb 6301

Question? 

Anton Rutkevich,

JunoLab

@AntonRutkevich

+AntonRutkevich

anton.rutkevich

Kotlin intro Mar 2016

By Anton Rutkevich

Kotlin intro Mar 2016

Kotlin intro, March 2016

  • 1,157