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

How to Kotlin のセッションからKotlinらしい表現を学ぶ / learn_ho...

How to Kotlin のセッションからKotlinらしい表現を学ぶ / learn_how_to_kotlin

「集まれKotlin好き!Kotlin愛好会 vol1・How to Kotlin のセッションからKotlinらしい表現を学ぶ」の資料になります

sasami

May 30, 2018
Tweet

More Decks by sasami

Other Decks in Programming

Transcript

  1. Target session — How to Kotlin - from the Lead

    Kotlin Language Designer (Google I/O '18) — Andrey Breslav — Live Coding ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  2. Overview 1. class 2. Property 3. DSLs 4. Expression 5.

    Lambdas 6. Coroutines 7. Lazy Sequence ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  3. 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
  4. 1-2: class fun parseName(name: String): List<String> { val space =

    name.indexOf(' ') return listOf( name.substring(0, space), name.substring(space + 1) ) } fun main(args: Array<String>) { 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
  5. 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<String>) { 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
  6. 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<String>) { 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
  7. 2-1 Property private var prop: String = "..." fun getProp()

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

    set(v) { println("New value: $v") field = v } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  9. 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<String>) { for (i in 1..3) { println(os) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  10. 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<String>) { for (i in 1..3) { println(os) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  11. 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<String>) { println("\n\nObservable property:") observeMe = "bb" observeMe = "ccc" observeMe = "dddd" } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  12. 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
  13. 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
  14. 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<String>) { println( StringUtils().getFirstWord("Jane Doe") ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  15. 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<String>) { println( StringUtils.getFirstWord("Jane Doe") ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  16. 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<String>) { println( StringUtils.getFirstWord("Jane Doe") ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  17. 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<String>) { println( getFirstWord("Jane Doe", separator = “, ”) ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  18. 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<String>) { println( "Jane Doe".getFirstWord() ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  19. 2-5 Property val String.firstWord: String get() { val index =

    indexOf(" ") return if (index < 0) this else substring(0, index) } fun main(args: Array<String>) { println( "Jane Doe".firstWord ) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  20. 3-1 DSLs fun main(args: Array<String>) { val root = Container(

    Text("a"), Container( Text("b"), Container( Text("c"), Text("d") ), Text("e") ), Text("f") ) println(root) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 4-1 expression class Example(val a: Int, val b: String?, val

    c: Boolean) fun main(args: Array<String>) { 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
  28. 4-1 expression val ex = Example(1, null, true) with(ex) {

    println("a = $a, b = $b, c = $c") } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  29. 4-2 expression val map = HashMap<String, Int>() 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
  30. 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
  31. 4-3 expression val s: String if (System.currentTimeMillis() % 2L ==

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

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

    0L) { println("Yay!") "Luck!" } else { "Not this time" } println(s) ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  34. 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
  35. 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
  36. 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
  37. 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
  38. 5-1 lambdas fun main(args: Array<String>) { val numbers = (1..100).toList()

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

    val list = numbers .filter { it % 16 == 0 } .map { "0x" + it.toString(16) } println(list) } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  40. 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
  41. 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
  42. 6-1 coroutines fun main(args: Array<String>){ 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
  43. 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
  44. 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
  45. 6-2 coroutines suspend fun CallbackService.request(from: String) = suspendCoroutine<CallbackService.Response> { cont

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

    -> try { request(from) { r -> //called after execution is finished cont.resume(r) } } catch (e: Throwable) { cont.resumeWithException(e) } } ू·ΕKotlin޷͖ʂKotlinѪ޷ձ vol1
  47. 7-1 lazy sequence fun main(args: Array<String>) { 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
  48. 7-1 lazy sequence fun main(args: Array<String>) { 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