Kotlin Fest 2019: Kotlin型実践入門

Kotlin Fest 2019: Kotlin型実践入門

KotlinではJavaにはない様々な型に関する機能が追加されたので、それらの解説

- Smart Casts
- Any、Unit、Nothing
- ジェネリクス
- Sealed class
- 関数型

2793f1fe246c9299c2416062d22bfb99?s=128

Sato Shun

August 24, 2019
Tweet

Transcript

  1. 1.

    Kotlin Fest 2019 ࠤ౻ ൏ / Sato Shun Twitter: @stsn_jp

    GitHub: satoshun Kotlinܕ࣮ફೖ໳
  2. 6.

    Smart Casts • ifࣜɺwhenࣜɺisɺasͳͲͷ࣮ߦޙʹɺ໌ࣔతʹܕΩϟετ ͠ͳͯ͘΋ɺܕΛਪ࿦ͯ͘͠ΕΔ • flow-sensitive typing (flow typing)ͱݺ͹ΕΔܕγεςϜ

    • ৑௕ͳܕΩϟετΛܰݮ͢Δ • ಈతܕ෇͚ݴޠͷμοΫλΠϐϯάͷΑ͏ͳॻ͖৺஍ • https://en.wikipedia.org/wiki/Flow-sensitive_typing
  3. 7.

    if (obj is String) { a print((obj as String).length) }

    a if (obj !is String) return print((obj as String).length) when (obj) { aa is Int -> print((obj as Int) + 1) is String -> print((obj as String).length + 1) is IntArray -> print((obj as IntArray).sum() + 1) } a
  4. 8.

    if (obj is String) { a print(obj.length) } a if

    (obj !is String) return print((obj as String).length) when (obj) { aa is Int -> print((obj as Int) + 1) is String -> print((obj as String).length + 1) is IntArray -> print((obj as IntArray).sum() + 1) } a
  5. 9.

    if (obj is String) { a print(obj.length) } a if

    (obj !is String) return print(obj.length) when (obj) { aa is Int -> print((obj as Int) + 1) is String -> print((obj as String).length + 1) is IntArray -> print((obj as IntArray).sum() + 1) } a
  6. 10.

    if (obj is String) { a print(obj.length) } a if

    (obj !is String) return print(obj.length) when (obj) { a is Int -> print(obj + 1) is String -> print(obj.length + 1) is IntArray -> print(obj.sum() + 1) } a
  7. 11.

    if (hoge() && obj is Int) { a (obj as

    Int).toLong() } a if (obj is String && obj is Int) { a (obj as String).length (obj as Int).toLong() } a
  8. 12.

    if (hoge() && obj is Int) { a obj.toLong() }

    a if (obj is String && obj is Int) { a (obj as String).length (obj as Int).toLong() } a
  9. 13.

    if (hoge() && obj is Int) { a obj.toLong() }

    a if (obj is String && obj is Int) { a obj.length obj.toLong() } a
  10. 14.

    class Hoge { a private var obj: Any = "a"

    fun test() { a if (obj is String) { a print((obj as String).length) } a } a } a
  11. 15.

    class Hoge { a private var obj: Any = "a"

    fun test() { a if (obj is String) { a print(obj.length) } a } a } a
  12. 16.

    class Hoge { a private var obj: Any = "a"

    fun test() { a if (obj is String) { a print(obj.length) } a } a } a ❌
  13. 17.

    class Hoge { a private var obj: Any = "a"

    fun test() { a val obj = obj if (obj is String) { a print(obj.length) } a } a } a
  14. 18.

    class Hoge { a private var obj: Any = "a"

    fun test() { a obj.let { a if (it is String) { a print(it.length) } a } a } a } a
  15. 22.

    public inline fun <T> Collection<T>?.isNullOrEmpty(): Boolean { a contract {

    a returns(false) implies (this@isNullOrEmpty != null) } a return this == null || this.isEmpty() } a
  16. 23.

    public inline fun <T> Collection<T>?.isNullOrEmpty(): Boolean { a contract {

    a returns(false) implies (this@isNullOrEmpty != null) } a return this == null || this.isEmpty() } a
  17. 24.

    public inline fun <T> Collection<T>?.isNullOrEmpty(): Boolean { a contract {

    a returns(false) implies (this@isNullOrEmpty != null) } a return this == null || this.isEmpty() } a
  18. 25.

    public inline fun <T> Collection<T>?.isNullOrEmpty(): Boolean { a contract {

    a returns(false) implies (this@isNullOrEmpty != null) } a return this == null || this.isEmpty() } a
  19. 28.

    fun assertTrue(actual: Boolean, message: String? = null) { a contract

    { returns() implies actual } a return asserter.assertTrue(message ?: "Expected value to be true.", actual) } a
  20. 29.

    fun assertTrue(actual: Boolean, message: String? = null) { a contract

    { returns() implies actual } a return asserter.assertTrue(message ?: "Expected value to be true.", actual) } a
  21. 30.

    fun assertTrue(actual: Boolean, message: String? = null) { a contract

    { returns() implies actual } a return asserter.assertTrue(message ?: "Expected value to be true.", actual) } a assertTrue(obj != null) print(obj!!.length)
  22. 31.

    fun assertTrue(actual: Boolean, message: String? = null) { a contract

    { returns() implies actual } a return asserter.assertTrue(message ?: "Expected value to be true.", actual) } a assertTrue(obj != null) print(obj.length)
  23. 32.

    fun assertFalse(actual: Boolean, message: String? = null) { contract {

    returns() implies (!actual) } return asserter.assertTrue(message ?: "Expected value to be false.", !actual) } assertFalse(obj == null) print(obj.length)
  24. 33.

    fun assertFalse(actual: Boolean, message: String? = null) { contract {

    returns() implies (!actual) } return asserter.assertTrue(message ?: "Expected value to be false.", !actual) } assertFalse(obj == null) print(obj.length)
  25. 34.

    public inline fun <R> run(block: () -> R): R {

    a contract { a callsInPlace(block, InvocationKind.EXACTLY_ONCE) } a return block() } a
  26. 35.

    public inline fun <R> run(block: () -> R): R {

    a contract { a callsInPlace(block, InvocationKind.EXACTLY_ONCE) } a return block() } a
  27. 36.

    public inline fun <R> run(block: () -> R): R {

    a contract { a callsInPlace(block, InvocationKind.EXACTLY_ONCE) } a return block() } a var s: String? = null a run { a s = "" a } a println(s!!) a
  28. 37.

    public inline fun <R> run(block: () -> R): R {

    a contract { a callsInPlace(block, InvocationKind.EXACTLY_ONCE) } a return block() } a val s: String a run { a s = "" a } a println(s) a
  29. 38.

    fun checkObj(obj: Any?): Boolean { a return obj != null

    } a if (checkObj(obj)) { a obj!!.javaClass } a
  30. 39.

    fun checkObj(obj: Any?): Boolean { a contract { a returns(true)

    implies (obj != null) } a return obj != null } a if (checkObj(obj)) { a obj!!.javaClass } a
  31. 40.

    fun checkObj(obj: Any?): Boolean { a contract { a returns(true)

    implies (obj != null) } a return obj != null } a if (checkObj(obj)) { a obj!!.javaClass } a
  32. 41.

    fun checkObj(obj: Any?): Boolean { a contract { a returns(true)

    implies (obj != null) } a return obj != null } a if (checkObj(obj)) { a obj!!.javaClass } a
  33. 42.

    fun checkObj(obj: Any?): Boolean { a contract { a returns(true)

    implies (obj != null) } a return obj != null } a if (checkObj(obj)) { a obj.javaClass } a
  34. 43.

    @UseExperimental(ExperimentalContracts::class) fun checkObj(obj: Any?): Boolean { a contract { a

    returns(true) implies (obj != null) } a return obj != null } a if (checkObj(obj)) { a obj.javaClass } a
  35. 52.
  36. 55.

    fun getName(): String { a return "name" } a fun

    fail() { a throw RuntimeException() } a
  37. 56.

    fun getName(): String { a return "name" } a fun

    fail() { a throw RuntimeException() } a val name = if (isFriend()) { a getName() } a else { a fail() } a
  38. 57.

    fun getName(): String { a return "name" } a fun

    fail() { a throw RuntimeException() } a val name: Any = if (isFriend()) { a getName() } a else { a fail() } a
  39. 58.

    fun getName(): String { a return "name" } a fun

    fail() { a throw RuntimeException() } a val name: Any = if (isFriend()) { a getName() } a else { a fail() } a
  40. 59.

    fun getName(): String { a return "name" } a fun

    fail() { a throw RuntimeException() } a val name: Any = if (isFriend()) { a getName() } a else { a fail() } a println((name as String).length)
  41. 60.

    fun getName(): String { a return "name" } a fun

    fail(): Nothing { a throw RuntimeException() } a val name: Any = if (isFriend()) { a getName() } a else { a fail() } a println((name as String).length)
  42. 61.

    fun getName(): String { a return "name" } a fun

    fail(): Nothing { a throw RuntimeException() } a val name: Any = if (isFriend()) { a getName() } a else { a fail() } a println((name as String).length)
  43. 62.

    fun getName(): String { a return "name" } a fun

    fail(): Nothing { a throw RuntimeException() } a val name: Any = if (isFriend()) { a getName() } a else { a fail() } a println((name as String).length)
  44. 63.

    fun getName(): String { a return "name" } a fun

    fail(): Nothing { a throw RuntimeException() } a val name: String = if (isFriend()) { a getName() } a else { a fail() } a println((name as String).length)
  45. 64.

    fun getName(): String { a return "name" } a fun

    fail(): Nothing { a throw RuntimeException() } a val name: String = if (isFriend()) { a getName() } a else { a fail() } a println(name.length)
  46. 65.

    fun getName(): String { a return "name" } a fun

    fail(): Nothing { a throw RuntimeException() } a val name = if (isFriend()) { a getName() } a else { a fail() } a println(name.length)
  47. 66.

    fun test(any: Any): String { a when (any) { a

    is Int -> return "int" else -> fail() } a return "error" } a
  48. 67.

    fun test(any: Any): String { a when (any) { a

    is Int -> return "int" else -> fail() } a return "error" } a NothingܕͳͷͰɺ͜ͷݺͼग़͠͸ਖ਼ৗʹऴྃ͠ͳ͍ ͜ͷelse͸ඞࣦͣഊ͢Δ
  49. 68.

    fun test(any: Any): String { a when (any) { a

    is Int -> return "int" else -> fail() } a } a
  50. 69.

    // ඪ४ؔ਺ public inline fun TODO(): Nothing = throw NotImplementedError()

    // KotlinTest fun fail(msg: String): Nothing = throw Failures.failure(msg)
  51. 70.

    // Kotlin/kotlinx.collections.immutable internal companion object { internal val EMPTY =

    TrieNode<Nothing>(0, emptyArray()) } // airbnb/MvRx object Uninitialized : Async<Nothing>(complete = false, shouldLoad = true), Incomplete
  52. 74.

    // kotlintest/kotlintest interface Show<in A> { a fun supports(a: Any?):

    Boolean fun show(a: A): String } a object NullShow : Show<Nothing?> { a override fun supports(a: Any?): Boolean = a == null override fun show(a: Nothing?): String = "<null>" } a
  53. 77.

    ෼ࢄΞϊςʔγϣϯ • out - ڞม: covariance • in - ൓ม:

    contravariance • ࢦఆͳ͠: ෆม: invariance
  54. 83.

    ڞมɺ൓มɺෆม • Number <|- Intͷܧঝؔ܎͕͋Δ • A<Number> <|- A<Int>ͷ৔߹ɺA͸ڞมͰ͋Δ •

    A<Number> -|> A<Int>ͷ৔߹ɺA͸൓มͰ͋Δ • A<Number>ɺ A<Int>͕ؔ܎ͳ͍৔߹ɺA͸ෆมͰ͋Δ
  55. 84.

    ڞมɺ൓มɺෆม • Number <|- Intͷܧঝؔ܎͕͋Δ • A<Number> <|- A<Int>ͷ৔߹ɺA͸ڞมͰ͋Δ •

    A<Number> -|> A<Int>ͷ৔߹ɺA͸൓มͰ͋Δ • A<Number>ɺ A<Int>͕ؔ܎ͳ͍৔߹ɺA͸ෆมͰ͋Δ
  56. 86.

    // ڞม val a: A<Int> = A<Int>() a val b:

    A<Number> = a // ൓ม val a: A<Number> = A<Number>() a val b: A<Int> = a
  57. 87.

    // ڞม val a: A<Int> = A<Int>() a val b:

    A<Number> = a // ൓ม val a: A<Number> = A<Number>() a val b: A<Int> = a // ෆม val a: A<Int> = A<Int>() a
  58. 88.

    interface Mapper<T> { a fun map(s: String): T } a

    class IntMapper : Mapper<Int> { a override fun map(s: String): Int = s.toInt() } a
  59. 89.

    interface Mapper<T> { a fun map(s: String): T } a

    class IntMapper : Mapper<Int> { a override fun map(s: String): Int = s.toInt() } a fun hoge(mapper: Mapper<Number>) { a mapper.map("10") } a
  60. 90.

    interface Mapper<T> { a fun map(s: String): T } a

    class IntMapper : Mapper<Int> { a override fun map(s: String): Int = s.toInt() } a fun hoge(mapper: Mapper<Number>) { a mapper.map("10") } a val mapper = IntMapper() hoge(mapper)
  61. 91.

    interface Mapper<T> { a fun map(s: String): T } a

    class IntMapper : Mapper<Int> { a override fun map(s: String): Int = s.toInt() } a fun hoge(mapper: Mapper<Number>) { a mapper.map("10") } a val mapper = IntMapper() hoge(mapper) ❌
  62. 92.

    interface Mapper<T> { a fun map(s: String): T } a

    class IntMapper : Mapper<Int> { a override fun map(s: String): Int = s.toInt() } a fun hoge(mapper: Mapper<Number>) { a mapper.map("10") } a val mapper = IntMapper() hoge(mapper) ❌
  63. 93.

    interface Mapper<out T> { a fun map(s: String): T }

    a class IntMapper : Mapper<Int> { a override fun map(s: String): Int = s.toInt() } a fun hoge(mapper: Mapper<Number>) { a mapper.map("10") } a val mapper = IntMapper() hoge(mapper) ❌
  64. 94.

    interface Mapper<out T> { a fun map(s: String): T }

    a class IntMapper : Mapper<Int> { a override fun map(s: String): Int = s.toInt() } a fun hoge(mapper: Mapper<Number>) { a mapper.map("10") } a val mapper = IntMapper() hoge(mapper) ❌
  65. 95.

    interface Mapper<out T> { a fun map(s: String): T }

    a class IntMapper : Mapper<Int> { a override fun map(s: String): Int = s.toInt() } a fun hoge(mapper: Mapper<Number>) { a mapper.map("10") } a val mapper = IntMapper() hoge(mapper)
  66. 97.

    ListͱMutableList public interface List<out E> : Collection<E> public interface MutableList<E>

    : List<E>, … • List͸outम০ࢠ͕෇͍͍ͯΔͷͰɺڞม • MutableList͸Կ΋෇͍͍ͯͳ͍ͷͰɺෆม
  67. 101.

    val strs: List<String> = listOf("a", “b") val anys: List<Any> =

    strs val a: Any = anys[0] val a2: Any? = anys2.getOrNull(1)
  68. 102.

    val strs: List<String> = listOf("a", “b") val anys: List<Any> =

    strs val a: Any = anys[0] val a2: Any? = anys2.getOrNull(1)
  69. 108.
  70. 110.

    PECS • Producer Extends Consumer Super • Producer͸readͷੑ࣭Λ࣋ͭ • Consumer͸writeͷੑ࣭Λ࣋ͭ

    • List͸Producerͷੑ࣭ͷΈΛ࣋ͭͷͰɺExtends = out ڞมʹ ग़དྷΔ • MutableList͸ProducerͱConsumerͷੑ࣭Λ࣋ͭͷͰɺෆม
  71. 113.

    2ͭҎ্ͷ্քΛ࣋ͭܕม਺ • 1ͭͷ্քʢupper boundʣΛ࣋ͭͱ͖͸ɺׅހ಺ʹॻ͚͹ྑ ͍ • fun <T : CharSequence>

    hoge(t: T) {…} • 2ͭҎ্ͷ্քΛ࣋ͭ৔߹͸Ͳ͏͢Ε͹Α͍͔ʁ • ྫ͑͹ɺActivity͔ͭOnClickListenerΛ࣋ͭܕΛड͚ೖΕΔܕ ม਺Λఆ͍ٛͨ͠
  72. 117.

    class OnClickActivity() : Activity(), OnClickListener fun setClick(activity: OnClickActivity) { a

    } a val activity = OnClickActivity() setClick(activity) class OnClickActivity2() : Activity(), OnClickListener
  73. 118.

    class OnClickActivity() : Activity(), OnClickListener fun setClick(activity: OnClickActivity) { a

    } a val activity = OnClickActivity() setClick(activity) class OnClickActivity2() : Activity(), OnClickListener val activity2 = OnClickActivity2() setClick(activity2)
  74. 119.

    class OnClickActivity() : Activity(), OnClickListener fun setClick(activity: OnClickActivity) { a

    } a val activity = OnClickActivity() setClick(activity) class OnClickActivity2() : Activity(), OnClickListener val activity2 = OnClickActivity2() setClick(activity2) ❌
  75. 123.

    fun <T> setClick(activity: T) where T : Activity, T :

    OnClickListener { a } a val activity = OnClickActivity() setClick(activity)
  76. 124.

    fun <T> setClick(activity: T) where T : Activity, T :

    OnClickListener { } val activity = OnClickActivity() setClick(activity) val activity2 = OnClickActivity2() setClick(activity2)
  77. 125.

    internal abstract class NIOSocketImpl<out S>( override val channel: S, val

    selector: SelectorManager, val pool: ObjectPool<ByteBuffer>? ) : ReadWriteSocket, SelectableBase(channel), CoroutineScope where S : java.nio.channels.ByteChannel, S : java.nio.channels.SelectableChannel Ktor
  78. 126.

    internal abstract class NIOSocketImpl<out S>( override val channel: S, val

    selector: SelectorManager, val pool: ObjectPool<ByteBuffer>? ) : ReadWriteSocket, SelectableBase(channel), CoroutineScope where S : java.nio.channels.ByteChannel, S : java.nio.channels.SelectableChannel Ktor
  79. 127.

    internal abstract class NIOSocketImpl<out S>( override val channel: S, val

    selector: SelectorManager, val pool: ObjectPool<ByteBuffer>? ) : ReadWriteSocket, SelectableBase(channel), CoroutineScope where S : java.nio.channels.ByteChannel, S : java.nio.channels.SelectableChannel internal class DatagramSocketImpl(override val channel: DatagramChannel, selector: SelectorManager) : BoundDatagramSocket, ConnectedDatagramSocket, NIOSocketImpl<DatagramChannel>(channel, selector, DefaultDatagramByteBufferPool) Ktor
  80. 128.

    internal abstract class NIOSocketImpl<out S>( override val channel: S, val

    selector: SelectorManager, val pool: ObjectPool<ByteBuffer>? ) : ReadWriteSocket, SelectableBase(channel), CoroutineScope where S : java.nio.channels.ByteChannel, S : java.nio.channels.SelectableChannel internal class DatagramSocketImpl(override val channel: DatagramChannel, selector: SelectorManager) : BoundDatagramSocket, ConnectedDatagramSocket, NIOSocketImpl<DatagramChannel>(channel, selector, DefaultDatagramByteBufferPool) internal class SocketImpl<out S : SocketChannel>( override val channel: S, private val socket: java.net.Socket, selector: SelectorManager ) : NIOSocketImpl<S>(channel, selector, pool = null), Socket Ktor
  81. 130.

    inline fun <reified T> hoge(obj: Any) { a println(T::class.java) a

    if (obj is T) { a println("obj is T") a } a } a
  82. 131.

    inline fun <reified T> hoge(obj: Any) { a println(T::class.java) a

    if (obj is T) { a println("obj is T") a } a } a
  83. 132.

    inline fun <reified T> hoge(obj: Any) { a println(T::class.java) a

    if (obj is T) { a println("obj is T") a } a } a
  84. 134.
  85. 135.

    class A<T>(val value: T) { a fun isNull(): Boolean {

    a return value != null } a } a val a1: A<Int?> = A(null) a a1.isNull() a
  86. 136.

    class A<T>(val value: T) { a fun isNull(): Boolean {

    a return value != null } a } a val a1: A<Int?> = A(null) a a1.isNull() a val a2: A<Int> = A(10) a a2.isNull() a
  87. 137.

    class A<T>(val value: T) a fun <T : Any> A<T?>.isNull():

    Boolean { a return value != null a } a val a1: A<Int?> = A(null) a a1.isNull() a val a2: A<Int> = A(10) a a2.isNull() a
  88. 138.

    class A<T>(val value: T) a fun <T : Any> A<T?>.isNull():

    Boolean { a return value != null a } a val a1: A<Int?> = A(null) a a1.isNull() a val a2: A<Int> = A(10) a a2.isNull() a
  89. 139.

    class A<T>(val value: T) a fun <T : Any> A<T?>.isNull():

    Boolean { a return value != null a } a val a1: A<Int?> = A(null) a a1.isNull() a val a2: A<Int> = A(10) a a2.isNull() a
  90. 140.

    class A<T>(val value: T) a fun <T : Any> A<T?>.isNull():

    Boolean { a return value != null a } a val a1: A<Int?> = A(null) a a1.isNull() a val a2: A<Int> = A(10) a a2.isNull() a ❌
  91. 143.

    abstract class Either object Left : Either() object Right :

    Either() when (obj) { a Left -> println("is Left") Right -> println("is Right") else -> println("else") } a
  92. 144.

    sealed class Either object Left : Either() object Right :

    Either() when (obj) { a Left -> println("is Left") Right -> println("is Right") else -> println("else") } a
  93. 145.

    sealed class Either object Left : Either() object Right :

    Either() when (obj) { a Left -> println("is Left") Right -> println("is Right") } a
  94. 147.

    public abstract class Either { private Either() { } //

    $FF: synthetic method public Either(DefaultConstructorMarker $constructor_marker) { this(); } }
  95. 148.

    public abstract class Either { private Either() { } //

    $FF: synthetic method public Either(DefaultConstructorMarker $constructor_marker) { this(); } }
  96. 154.
  97. 155.
  98. 156.

    fun add(a1: Int, a2: Int): Int { a return a1

    + a2 } a add add(10, 20) val a: (Int, Int) -> Int = ::add
  99. 157.

    fun add(a1: Int, a2: Int): Int { a return a1

    + a2 } a add add(10, 20) val a: (Int, Int) -> Int = ::add a(10, 20)
  100. 158.

    } a add add(10, 20) val a: (Int, Int) ->

    Int = ::add a(10, 20) fun <P1, P2, R> ((P1, P2) -> R).curried(): (P1) -> (P2) -> R = { p1: P1 -> { p2: P2 -> this(p1, p2) } } a
  101. 159.

    } a add add(10, 20) val a: (Int, Int) ->

    Int = ::add a(10, 20) fun <P1, P2, R> ((P1, P2) -> R).curried(): (P1) -> (P2) -> R = { p1: P1 -> { p2: P2 -> this(p1, p2) } } a
  102. 160.

    } a add add(10, 20) val a: (Int, Int) ->

    Int = ::add a(10, 20) fun <P1, P2, R> ((P1, P2) -> R).curried(): (P1) -> (P2) -> R = { p1: P1 -> { p2: P2 -> this(p1, p2) } } a
  103. 161.

    } a add add(10, 20) val a: (Int, Int) ->

    Int = ::add a(10, 20) fun <P1, P2, R> ((P1, P2) -> R).curried(): (P1) -> (P2) -> R = { p1: P1 -> { p2: P2 -> this(p1, p2) } } a val curried = a.curried()
  104. 162.

    } a add add(10, 20) val a: (Int, Int) ->

    Int = ::add a(10, 20) fun <P1, P2, R> ((P1, P2) -> R).curried(): (P1) -> (P2) -> R = { p1: P1 -> { p2: P2 -> this(p1, p2) } } a val curried = a.curried() curried(10)(20)
  105. 163.

    class A : (Int) -> Unit { a override fun

    invoke(p1: Int) { a println("call $p1") } a } a val a = A() a.invoke(10)
  106. 164.

    class A : (Int) -> Unit { a override fun

    invoke(p1: Int) { a println("call $p1") } a } a val a = A() a(10)
  107. 165.
  108. 166.

    public interface Function1<in P1, out R> : Function<R> { public

    operator fun invoke(p1: P1): R } a val a: (Number) -> Number = { it } a
  109. 167.

    public interface Function1<in P1, out R> : Function<R> { public

    operator fun invoke(p1: P1): R } a val a: (Number) -> Number = { it } a val a1: (Int) -> Number = a
  110. 168.

    public interface Function1<in P1, out R> : Function<R> { public

    operator fun invoke(p1: P1): R } a val a: (Number) -> Number = { it } a val a1: (Int) -> Number = a
  111. 169.

    public interface Function1<in P1, out R> : Function<R> { public

    operator fun invoke(p1: P1): R } a val a: (Number) -> Number = { it } a val a1: (Int) -> Number = a val a2: (Number) -> Any = a
  112. 170.

    public interface Function1<in P1, out R> : Function<R> { public

    operator fun invoke(p1: P1): R } a val a: (Number) -> Number = { it } as val a1: (Int) -> Number = a val a2: (Number) -> Any = a
  113. 171.

    SAMม׵ • SAM? • Single Abstract Method • 1ͭͷந৅ϝιουΛ࣋ͭ •

    Kotlin͔ΒJavaఆٛͷSAMΛ࢖͏ͱ͖ʹɺϥϜμࣜͰ؆ܿʹ ॻ͘͜ͱ͕ग़དྷΔ
  114. 172.

    public class SamTest { a public static void foo(Runnable a,

    Runnable b) { a } a } a fun test() { a SamTest.foo({}) { a } a } a
  115. 173.

    public class SamTest { a public static void foo(Runnable a,

    Runnable b) { a } a } a fun test() { a SamTest.foo({}) { a } a } a public interface Runnable { public abstract void run(); }
  116. 174.

    public class SamTest { a public static void foo(Runnable a,

    Runnable b) { a } a } a fun test(r: Runnable) { a SamTest.foo(r) { } } a
  117. 175.

    public class SamTest { a public static void foo(Runnable a,

    Runnable b) { a } a } a fun test(r: Runnable) { a SamTest.foo(r) { } } a ❌
  118. 177.

    // RxJava val o1 = Observable.just(1) val o2 = Observable.just(2)

    val combination = Observable .combineLatest(o1, o2, { n1, n2 -> n1 to n2 }) a
  119. 178.

    // RxJava val o1 = Observable.just(1) val o2 = Observable.just(2)

    val combination = Observable .combineLatest(o1, o2, { n1, n2 -> n1 to n2 }) public static <T1, T2, R> Observable<R> combineLatest( ObservableSource<? extends T1> source1, ObservableSource<? extends T2> source2, BiFunction<? super T1, ? super T2, ? extends R> combiner ) a
  120. 179.

    // RxJava val o1 = Observable.just(1) val o2 = Observable.just(2)

    val combination = Observable .combineLatest(o1, o2, { n1, n2 -> n1 to n2 }) public static <T1, T2, R> Observable<R> combineLatest( ObservableSource<? extends T1> source1, ObservableSource<? extends T2> source2, BiFunction<? super T1, ? super T2, ? extends R> combiner ) a public interface ObservableSource<T> { a void subscribe(@NonNull Observer<? super T> observer); } ˇ
  121. 180.

    // RxJava val o1 = Observable.just(1) val o2 = Observable.just(2)

    val combination = Observable .combineLatest(o1, o2, { n1, n2 -> n1 to n2 })
  122. 181.

    // RxJava val o1 = Observable.just(1) val o2 = Observable.just(2)

    val combination = Observable .combineLatest(o1, o2, { n1, n2 -> n1 to n2 }) ❌
  123. 182.

    // RxJava val o1 = Observable.just(1) val o2 = Observable.just(2)

    val combination = Observable .combineLatest(o1, o2, BiFunction { n1, n2 -> n1 to n2 })
  124. 183.

    public static <T1, T2, R> Observable<R> combineLatest( ObservableSource<? extends T1>

    source1, ObservableSource<? extends T2> source2, BiFunction<? super T1, ? super T2, ? extends R> combiner ) a
  125. 184.

    public static <T1, T2, R> Observable<R> combineLatest( Observable<? extends T1>

    source1, Observable<? extends T2> source2, BiFunction<? super T1, ? super T2, ? extends R> combiner ) a
  126. 185.

    public static <T1, T2, R> Observable<R> combineLatest( Observable<? extends T1>

    source1, Observable<? extends T2> source2, BiFunction<? super T1, ? super T2, ? extends R> combiner ) a val o1 = Observable.just(1) val o2 = Observable.just(2) val combination = Observable .combineLatest(o1, o2, BiFunction { n1, n2 -> n1 to n2 })
  127. 186.

    public static <T1, T2, R> Observable<R> combineLatest( Observable<? extends T1>

    source1, Observable<? extends T2> source2, BiFunction<? super T1, ? super T2, ? extends R> combiner ) a val o1 = Observable.just(1) val o2 = Observable.just(2) val combination = Observable .combineLatest(o1, o2, { n1, n2 -> n1 to n2 })
  128. 189.

    Kotlin Fest 2019 ࠤ౻ ൏ / Sato Shun Twitter: @stsn_jp

    GitHub: satoshun Kotlinܕ࣮ફೖ໳