4. Why is Kotlin
• Static Typing
• Java + Kotlin = ❤.
Effortless mixing both in one project
• Java Interoperability.
100% interoperable with Java.
4
5. Why is Kotlin
• Null Safety
• Type Inference
• Immutability in the mind
• fun
5
6. fun main(args : Array<String>) {
println("Hello, MO 2016!")
}
6
7. 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
8. Null Safety
// can’t be null
val foo: String = “mobile”
// need always perform the check
val bar: String? = null
8
Type? = Type or null
9. Null Safety
val bar: String? = “mobile”
var a = bar?.length // 6
var b = bar?.length?.inc() // 7
var c = bar!!.length // can be NPE
9
10. Null Safety
val bar: String? = null
var a = if (bar != null) bar.length
else 0 // 0
var b = bar?.length ?: 0 // 0
10
11. 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
12. Type Definition
class Phone(val brand: String){
var version: Int = 0
}
12
get() {…}
private set
val phone = Phone(“Apple”)
phone.brand == “Apple” // true
15. Delegates
15
class Foo<T> : List<T> {
private val innerList = arrayListOf<T>()
override val size: Int get() = innerList.size
override fun isEmpty() = innerList.isEmpty()
…
…
…
}
16. Delegates – right way
16
class Foo<T>
( innerList : List<T> = ArrayList<T>() )
: List<T> by innerList
All functions invocation delegated to innerList
17. Delegates – right way
17
class View {
}
val lazyProp by lazy { “mobile” }
val ops by observable(“”) {
prop, old, new ->
print("$old to $new")
}
18. 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!”)
}
19. Delegates – wow way
19
class SMS(val props: Map<String, String>) {
}
val date by props
val address by props
val info: String
get() {
“$date - $address”
}
20. Delegates – wow way
20
class SMS(val props: Map<String, String>) {
}
val date by props
val address by props
…
val props = mapOf(“date” to “128932”,
“address” to “Sweden”)
val sms = SMS(props)
print(sms.info) // “128932 - Sweden”
30. λ
30
boys.filter { it.age > 18 }
.map { Pair(it, Boy("Eugene")) }
.forEach { dance(it) }
// Under the hood
inline fun <T> Iterable<T>.filter
(predicate: (T) -> Boolean)
31. DSL
31
• Type-safe
• Express your code by flexible syntax
• Ideal to build own query engine
• if/for/when just inside DSL
32. 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~
33. 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 ……
}