Post on 14-Feb-2017
Let’s fly to the Kotlin island
short and comprehensive introduction
Aliaksei Zhynhiarouski
1
http://try.kotl.in
2
Kotlin Island3
Why is Kotlin• Static Typing
• Java + Kotlin = ❤. Effortless mixing both in one project
• Java Interoperability. 100% interoperable with Java.
4
Why is Kotlin• Null Safety
• Type Inference
• Immutability in the mind
• fun
5
fun main(args : Array<String>) {
println("Hello, MO 2016!")
}
6
val from_value : Type var from_variable : Type
val i_am_string = “mobile” var i_am_long = 666L val i_am_double = 3.14e10
7
val & var
Null Safety
// can’t be nullval foo: String = “mobile”
// need always perform the check val bar: String? = null
8
Type? = Type or null
Null Safetyval bar: String? = “mobile”
var a = bar?.length // 6var b = bar?.length?.inc() // 7var c = bar!!.length // can be NPE
9
Null Safetyval bar: String? = null
var a = if (bar != null) bar.length else 0 // 0var b = bar?.length ?: 0 // 0
10
Type Definition
class Phone(val brand: String)
11
• concise syntax for constructor • properties – not fields • final by default. Use open to open • simple old java class under the hood
Type Definition
class Phone(val brand: String){
var version: Int = 0
}
12
get() {…}private set
val phone = Phone(“Apple”) phone.brand == “Apple” // true
Value Object
data class Phone(val brand: String)
13
Lombok – no more
Get ready to be inspired
14
Delegates
15
class Foo<T> : List<T> {
private val innerList = arrayListOf<T>()
override val size: Int get() = innerList.size override fun isEmpty() = innerList.isEmpty() … … …
}
Delegates – right way
16
class Foo<T>
( innerList : List<T> = ArrayList<T>() )
: List<T> by innerList
All functions invocation delegated to innerList
Delegates – right way
17
class View {
}
val lazyProp by lazy { “mobile” }
val ops by observable(“”) { prop, old, new ->
print("$old to $new")
}
Delegates – wow way
18
class Activity {
}
private val btn: Button by lazy { findViewById(R.id.btn) as Button} override fun onCreate(savedBundle: Bundle?) { btn.setText(“Optimize!”) }
Delegates – wow way
19
class SMS(val props: Map<String, String>) {
}
val date by propsval address by propsval info: String get() { “$date - $address” }
Delegates – wow way
20
class SMS(val props: Map<String, String>) {
}
val date by propsval address by props…
val props = mapOf(“date” to “128932”, “address” to “Sweden”) val sms = SMS(props)
print(sms.info) // “128932 - Sweden”
Get ready to be inspired
21
Extensions
22
// Example“Mobile”.lastChar() // “e”
// Definitionfun String.lastChar():Char = this.get(length - 1)
Extensions
23
// Java under the hood@file:JvmName(“StringUtils") StringUtils.lastChar(“Mobile”);
Extensions
24
Collections.max(list)↓
list.max()
Extensions
25
operator fun BigDecimal.inc() = this + BigDecimal.ONE
// Examplevar counter = BigDecimal.ZEROprint(++counter) // 1
Fun
26
Named Parameters
// BadContentResolver.query(URI, new String[]{ }, null, null, null);
// GoodContentResolver.query(URI, projection = new String[]{ }, selection = null, selectionArgs = null, sortOrder = null)
Fun
27
Named Parameters & Default Values
// Bad IN_PROGRESS(true, false, false, false, false, false), FAILED (false, true, true, false, false, false), COMPLETE (true, false, true, false, false, true)// Good COMPLETE(stop = true, cancel = true, disable = true)
Fun
28
Named Parameters & Default Values
// Awesomeclass COMPLETE( stop: Boolean = false, cancel: Boolean = false, … …)
Lambdas
29
val boys = listOf( Boy(“Alex”), Boy(“Magnus”), Boy(“Nils”))
// 1 boys.filter({ b: Boy -> b.age > 18 })// 2boys.filter({ it.age > 18 })// 3boys.filter { it.age > 18 }
λ
30
boys.filter { it.age > 18 } .map { Pair(it, Boy("Eugene")) }.forEach { dance(it) }
// Under the hoodinline fun <T> Iterable<T>.filter (predicate: (T) -> Boolean)
DSL
31
• Type-safe
• Express your code by flexible syntax
• Ideal to build own query engine
• if/for/when just inside DSL
DSL
32
"(#C1 = :active) AND (#C2 = :type) AND " + "(attribute_not_exists(#C1) OR #C1 IN (:model, :allModels)) AND " + "...";if (smth)append("(#C2 = :active) AND NOT contains(#C3, :brandAll)");
…
// wait, oh shi~
DSL
33
val expr = filterExpr { group { eq("#1", ":2") and eq("#1", ":2") or group { eq("#2", ":2") if (smth) { and eq("#2", ":2") } } and …… }
One more DSL thing
34
Gradle meets Kotlin
Kotlin 1.1
• Direct Java 8/9 support
• Type aliases
• Delegated properties everywhere
• Coroutines with async/await
35
bit.ly/kotlin_11
Kotlin 1.1
typealias Callback<T> = (T) -> T
// And nowfun alias(cb: Callback<String>) {}
36
Type aliases
Kotlin 1.1
typealias Table<K> = MutableMap<K,MutableList<String>>
37
Type aliases
Kotlin 1.1
fun (cb: Callback<String>) { val callonce by lazy { cb("MO 2016") }
println(callonce)
}
38
Local delegated properties
Kotlin 1.1
val future = async<String> {
(1..5).map {
await(loooongAsyncOperation(it)) }.joinToString("\n")
}
39
Coroutines with async/await
LinksAwesome Kotlin kotlin.link
Slack kotlinlang.slack.com
Local Chat gitter.im/JavaBy/Kotlin
41
Start your journey with
42
twitter: @a_lithium