Slide 1

Slide 1 text

How to Kotlinͷηογϣϯ͔ΒKotlinΒ͍͠දݱΛֶͿ (from Google I/O 2018) @sasamihoo ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 2

Slide 2 text

Target session — How to Kotlin - from the Lead Kotlin Language Designer (Google I/O '18) — Andrey Breslav — Live Coding ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 3

Slide 3 text

Profile — @sasamihoo — ৘ใܥ(IoTܥ)ͷݚڀࣨ(M2) — Androidྺ2೥͘Β͍ ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 4

Slide 4 text

Overview 1. class 2. Property 3. DSLs 4. Expression 5. Lambdas 6. Coroutines 7. Lazy Sequence ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 5

Slide 5 text

1-1: class class Bean { private var name: String private var age: Int constructor(n: String, a: Int) { name = n age = a } fun getName(): String { return name } fun getAge(): Int { return age } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 6

Slide 6 text

1-1: class class Bean(val name: String, val age: Int) ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 7

Slide 7 text

1-2: class fun parseName(name: String): List { val space = name.indexOf(' ') return listOf( name.substring(0, space), name.substring(space + 1) ) } fun main(args: Array) { val name = parseName("Jane Doe") val first = name.first[0] val last = name.last[1] println("$first $last") if (name != parseName("Jane Doe")) { println("!!!!!!!!!!!!!!!!!!!!!") println("Equals does not work!!") println("!!!!!!!!!!!!!!!!!!!!!") } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 8

Slide 8 text

1-2: class class FullName(val first: String, val last: String) fun parseName(name: String): FullName { val space = name.indexOf(' ') return FullName( name.substring(0, space), name.substring(space + 1) ) } fun main(args: Array) { val name = parseName("Jane Doe") val first = name.first val last = name.last println("$first $last") if (name != parseName("Jane Doe")) { println("!!!!!!!!!!!!!!!!!!!!!") println("Equals does not work!!") println("!!!!!!!!!!!!!!!!!!!!!") } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 9

Slide 9 text

1-2: class data class FullName(val first: String, val last: String) fun parseName(name: String): FullName { val space = name.indexOf(' ') return FullName( name.substring(0, space), name.substring(space + 1) ) } fun main(args: Array) { val name = parseName("Jane Doe") val first = name.first val last = name.last println("$first $last") if (name != parseName("Jane Doe")) { println("!!!!!!!!!!!!!!!!!!!!!") println("Equals does not work!!") println("!!!!!!!!!!!!!!!!!!!!!") } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 10

Slide 10 text

2-1 Property private var prop: String = "..." fun getProp() = prop fun setProp(v: String) { println("New value: $v") prop = v } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 11

Slide 11 text

2-1 Property custom setter private var prop: String = "..." set(v) { println("New value: $v") field = v } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 12

Slide 12 text

2-2 Property private var _os: String? = null val os: String get() { if (_os == null) { println("Computing") _os = System.getProperty("os.name") + " v" + System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ")" } return _os!! } fun main(args: Array) { for (i in 1..3) { println(os) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 13

Slide 13 text

2-2 Property val os: String by lazy { println("Computing") System.getProperty("os.name") + " v" + System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ")" } fun main(args: Array) { for (i in 1..3) { println(os) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 14

Slide 14 text

2-3 Property ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 15

Slide 15 text

2-3 Property import kotlin.properties.Delegates var observeMe by Delegates.observable("a") { p, old, new -> println("$${p.name} goes $old -> $new") } fun main(args: Array) { println("\n\nObservable property:") observeMe = "bb" observeMe = "ccc" observeMe = "dddd" } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 16

Slide 16 text

2-4 Property var p1: String = "initial" get() { println("You read me") return field } set(v) { println("You write me") field = v } var p2: String = "initial" get() { println("You read me") return field } set(v) { println("You write me") field = v } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 17

Slide 17 text

2-4 Property var p3 by Prop("initial") var p4 by Prop("initial") var p5 by Prop("initial") class Prop(var field: String) { operator fun getValue(thisRef: Any?, p: KProperty<*>): String { println("You read me") return field } operator fun setValue(thisRef: Any?, p: KProperty<*>, v: String) { println("You write me") field = v } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 18

Slide 18 text

2-5 Property class StringUtils { fun getFirstWord(s: String, separator: String): String { val index = s.indexOf(separator) return if (index < 0) s else s.substring(0, index) } fun getFirstWord(s: String) = getFirstWord(s, "") } fun main(args: Array) { println( StringUtils().getFirstWord("Jane Doe") ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 19

Slide 19 text

2-5 Property object StringUtils { fun getFirstWord(s: String, separator: String): String { val index = s.indexOf(separator) return if (index < 0) s else s.substring(0, index) } fun getFirstWord(s: String) = getFirstWord(s, "") } fun main(args: Array) { println( StringUtils.getFirstWord("Jane Doe") ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 20

Slide 20 text

2-5 Property fun getFirstWord(s: String, separator: String): String { val index = s.indexOf(separator) return if (index < 0) s else s.substring(0, index) fun getFirstWord(s: String) = getFirstWord(s, "") } fun main(args: Array) { println( StringUtils.getFirstWord("Jane Doe") ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 21

Slide 21 text

2-5 Property fun getFirstWord(s: String, separator: String = " "): String { val index = s.indexOf(separator) return if (index < 0) s else s.substring(0, index) } fun main(args: Array) { println( getFirstWord("Jane Doe", separator = “, ”) ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 22

Slide 22 text

2-5 Property fun String.getFirstWord(separater: String = " "): String { val index = indexOf(separater) return if (index < 0) this else substring(0, index) } fun main(args: Array) { println( "Jane Doe".getFirstWord() ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 23

Slide 23 text

2-5 Property val String.firstWord: String get() { val index = indexOf(" ") return if (index < 0) this else substring(0, index) } fun main(args: Array) { println( "Jane Doe".firstWord ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 24

Slide 24 text

3-1 DSLs fun main(args: Array) { val root = Container( Text("a"), Container( Text("b"), Container( Text("c"), Text("d") ), Text("e") ), Text("f") ) println(root) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 25

Slide 25 text

3-1 DSLs abstract class Element class Container(vararg val children: Element) : Element() class Text(val text: String) : Element() fun Element.extractText(): String { return extractText(this, StringBuilder()).toString() } fun extractText(e: Element, sb: StringBuilder): StringBuilder { if (e is Text) { val text = e as Text sb.append(text.text) } else if (e is Container) { val container = e as Container for (child in container.children) { extractText(child, sb) } } else error("Unrecognised element: $e") return sb } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 26

Slide 26 text

3-1 DSLs fun Element.extractText(): String { val sb = StringBuilder() fun extractText(e: Element) { if (e is Text) { val text = e as Text sb.append(text.text) } else if (e is Container) { val container = e as Container for (child in container.children) { extractText(child) } } else error("Unrecognised element: $e") } extractText(this) return sb.toString() } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 27

Slide 27 text

3-1 DSLs fun Element.extractText(): String { val sb = StringBuilder() fun extractText(e: Element) { if (e is Text) { sb.append(e.text) } else if (e is Container) { for (child in e.children) { extractText(child) } } else error("Unrecognised element: $e") } extractText(this) return sb.toString() } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 28

Slide 28 text

3-1 DSLs fun Element.extractText(): String { val sb = StringBuilder() fun extractText(e: Element) { if (e is Text) { sb.append(e.text) } else if (e is Container) { e.children.forEach(::extractText) } else error("Unrecognised element: $e") } extractText(this) return sb.toString() } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 29

Slide 29 text

3-1 DSLs ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 30

Slide 30 text

3-2 DSLs fun Element.extractText(): String { val sb = StringBuilder() fun extractText(e: Element) { when (e) { is Text -> sb.append(e.text) is Container -> e.children.forEach(::extractText) else -> error("Unrecognized element: $e") } } extractText(this) return sb.toString() } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 31

Slide 31 text

3-2 DSLs sealed class Element class Container(vararg val children: Element) : Element() class Text(val text: String) : Element() fun Element.extractText(): String { val sb = StringBuilder() fun extractText(e: Element) { when (e) { is Text -> sb.append(e.text) is Container -> e.children.forEach(::extractText) } } extractText(this) return sb.toString() } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 32

Slide 32 text

4-1 expression class Example(val a: Int, val b: String?, val c: Boolean) fun main(args: Array) { val ex = Example(1, null, true) val a = ex.a val b = ex.b val c = ex.c println("a = " + a + ", b = " + b + ", c = " + c) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 33

Slide 33 text

4-1 expression val ex = Example(1, null, true) with(ex) { println("a = $a, b = $b, c = $c") } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 34

Slide 34 text

4-2 expression val map = HashMap() map.put("k1", 1) map.put("k2", 2) map.put("k3", 3) for (e in map.entries) { val key = e.key val value = e.value println(key + " -> " + value) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 35

Slide 35 text

4-2 expression val map = mapOf( "k1" to 1, "k2" to 2, "k3" to 3 ) for ((key, value) in map.entries) { println("$key -> $value") } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 36

Slide 36 text

4-3 expression val s: String if (System.currentTimeMillis() % 2L == 0L) { println("Yay!") "Luck!" } else { "Not this time" } println(s) ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 37

Slide 37 text

4-3 expression ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 38

Slide 38 text

4-3 expression val s: String = if (System.currentTimeMillis() % 2L == 0L) { println("Yay!") "Luck!" } else { "Not this time" } println(s) ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 39

Slide 39 text

4-3 expression val s = if (System.currentTimeMillis() % 2L == 0L) { println("Yay!") "Luck!" } else { "Not this time" } println(s) ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 40

Slide 40 text

4-4 expression fun test(e: Example): String { when (e.a) { 1 -> return "Even" 3 -> return "Even" 5 -> return "Even" 2 -> return "Odd" 4 -> return "Odd" 6 -> return "Odd" else -> "Too Big" } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 41

Slide 41 text

4-4 expression fun test(e: Example): String = when (e.a) { 1, 3, 5 -> "Even" in setOf(2, 4, 6) -> "Odd" else -> "Too Big" } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 42

Slide 42 text

4-5 expression fun test2(str: String?): String? { println(str?.length) str?.forEach(::println) if (str == null) return null if (str == null) throw RuntimeException("Unexpected null!!") if (str == null) error("Unexpected null") return "" } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 43

Slide 43 text

4-5 expression fun test2(str: String?): String? { println(str?.length) str?.forEach(::println) str ?: return null if (str == null) return null if (str == null) throw RuntimeException("Unexpected null!!") if (str == null) error("Unexpected null") return "" } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 44

Slide 44 text

5-1 lambdas fun main(args: Array) { val numbers = (1..100).toList() val list = mutableListOf() for (it in numbers) { if (it % 16 == 0) { list.add("0x" + it.toString(16)) } } println(list) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 45

Slide 45 text

5-1 lambdas ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 46

Slide 46 text

5-1 lambdas fun main(args: Array) { val numbers = (1..100).toList() val list = numbers .filter { it % 16 == 0 } .map { "0x" + it.toString(16) } println(list) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 47

Slide 47 text

5-2 lambdas … repeat(6) { println(list) } } inline fun repeat(times: Int, body: (Int) -> Unit) { for (index in 0 until times) { body(index) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 48

Slide 48 text

6-1 coroutines class CallbackService(val name: String) { class Response(val from: CallbackService, val message: String) fun request(from: String, callback: (Response) -> Unit) { //Do work... callback(Response(this, "Hi $from!\n -- Yours, $name")) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 49

Slide 49 text

6-1 coroutines fun main(args: Array){ val s1 = CallbackService("1") val s2 = CallbackService("2") s1.request(s2.name) { r1 -> println(r1.message) r1.from.request(s1.name) { r2 -> println(r2.message) } } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 50

Slide 50 text

6-1 coroutines fun CallbackService.sendMany(vararg from: String, callback: (CallbackService.Response) -> Unit) { if (from.isEmpty()) return this.request(from[0]) { r -> callback(r) sendMany(*from.copyOfRange(1, from.size), callback = callback) } } … s1.sendMany("a", "b", "c") { r -> println(r.message) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 51

Slide 51 text

6-2 coroutines runBlocking { val r1 = s1.request(s2.name) val r2 = s2.request(s1.name) for (from in listOf("a", "b", "c")) { println(s1.request(from).message) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 52

Slide 52 text

6-2 coroutines suspend fun CallbackService.request(from: String) = suspendCoroutine { cont -> request(from) { r -> //called after execution is finished cont.resume(r) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 53

Slide 53 text

6-2 coroutines suspend fun CallbackService.request(from: String) = suspendCoroutine { cont -> try { request(from) { r -> //called after execution is finished cont.resume(r) } } catch (e: Throwable) { cont.resumeWithException(e) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 54

Slide 54 text

7-1 lazy sequence fun main(args: Array) { val seq = buildSequence { var a = 1 var b = 1 while (true) { yield(a) val tmp = a a = b b += tmp } } println( seq.take(20).toList() ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 55

Slide 55 text

7-1 lazy sequence fun main(args: Array) { val seq = buildSequence { var a = 1 var b = 1 yield(2) while (true) { yield(a) val tmp = a if (tmp > 10) continue a = b b += tmp } } println( seq.take(20).toList() ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 56

Slide 56 text

LiveCodingͷॻ͖ى͜͠ ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 57

Slide 57 text

LiveCodingͷॻ͖ى͜͠ ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 58

Slide 58 text

LiveCodingͷ·ͶΛͯ͠Έͯ — ϖΞϓϩͬΆ͍͜ͱ͕Ͱ͖Δ(?) — ࣮ࡍʹखΛಈ͔͢͜ͱͰཧղ͕ਂ·Δ — ΍ͬͺΓ࣌ؒ͸͔͔Δ…(ࢿྉͱ߹Θͤͯ7࣌ؒ͘Β͍!) ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1

Slide 59

Slide 59 text

Thanks! ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1