Kotlin's Advanced Language Features

Kotlin's Advanced Language Features

05162bc961c3654218bf1839974a4f35?s=128

Benoît Quenaudon

October 18, 2018
Tweet

Transcript

  1. 5.

    fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val

    sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array<String>) {c }e
  2. 6.

    fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val

    sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array<String>) {c val s = buildString({ stringBuilder -> stringBuilder.append("Hello, ") stringBuilder.append("World!") })d }e
  3. 7.

    fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val

    sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array<String>) {c val s = buildString { stringBuilder -> stringBuilder.append("Hello, ") stringBuilder.append("World!") }d }e
  4. 8.

    fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val

    sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array<String>) {c val s = buildString { it.append("Hello, ") it.append("World!") }d }e
  5. 9.

    fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val

    sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array<String>) {c val s = buildString { append("Hello, ") append("World!") }d }e
  6. 10.

    fun buildString( builderAction: StringBuilder.() -> Unit ): String {a val

    sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array<String>) {c val s = buildString { append("Hello, ") append("World!") }d }e
  7. 11.

    fun buildString( builderAction: StringBuilder.() -> Unit ): String {a val

    sb = StringBuilder() sb.builderAction() return sb.toString() }b fun main(args: Array<String>) {c val s = buildString { append("Hello, ") append("World!") }d }e
  8. 12.

    fun buildString( builderAction: StringBuilder.() -> Unit ): String {a val

    sb = StringBuilder() sb.builderAction() return sb.toString() }b fun main(args: Array<String>) {c val s = buildString { append("Hello, ") append("World!") }d }e
  9. 13.

    fun buildString( builderAction: StringBuilder.() -> Unit ): String {a val

    sb = StringBuilder() sb.builderAction() return sb.toString() }b fun main(args: Array<String>) {c val s = buildString { this.append("Hello, ") append("World!") }d }e
  10. 14.
  11. 16.

    fun <T, R> with( receiver: T, block: T.() -> R

    ): R { return receiver.block() }
  12. 19.

    interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber

    fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d
  13. 20.

    interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber

    fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 }c }d
  14. 21.

    interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber

    fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d
  15. 22.

    interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber

    class Magic() : BinaryNumber() { fun abracadabra() { // ... } } fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d
  16. 23.

    interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber

    fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d
  17. 24.

    sealed class BinaryNumber object Zero : BinaryNumber() object One :

    BinaryNumber() fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d
  18. 25.

    sealed class BinaryNumber object Zero : BinaryNumber() object One :

    BinaryNumber() fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 }c }d
  19. 26.

    sealed class BinaryNumber object Zero : BinaryNumber() object One :

    BinaryNumber() class Magic() : BinaryNumber() {z fun abracadabra() {w // ... }t }r fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 }c }d
  20. 27.

    sealed class BinaryNumber object Zero : BinaryNumber() object One :

    BinaryNumber() class Magic() : BinaryNumber() {z fun abracadabra() {w // ... }t }r fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 }c }d
  21. 28.

    sealed class BinaryNumber object Zero : BinaryNumber() object One :

    BinaryNumber() class Magic() : BinaryNumber() {z fun abracadabra() {w // ... }t }r fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 is Magic -> this.abracadabra() }c }d
  22. 29.

    sealed class BinaryNumber object Zero : BinaryNumber() object One :

    BinaryNumber() class Magic() : BinaryNumber() { fun abracadabra() { // ... } } fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 is Magic -> this.abracadabra() }c }d
  23. 30.
  24. 32.

    fun requireNotNull(obj: Any?) {a if (obj == null) throw IllegalArgumentException()

    }d fun foo(s: String?) {e requireNotNull(s) s.length }f
  25. 33.

    fun requireNotNull(obj: Any?) {a contract { returns() implies (obj !=

    null) }c if (obj == null) throw IllegalArgumentException() }d fun foo(s: String?) {e requireNotNull(s) s.length }f
  26. 34.
  27. 41.

    people // List<People> .asSequence() // Sequence<People> .map(People::name) // Sequence<String> .filter

    { it.startsWith("J") } // Sequence<String> .toList() // List<People>
  28. 45.
  29. 47.

    fun sumUp(items: Collection<*>) {a if (items is List<Int>) {d println(ints.sum())

    }b }c val strings: List<String> = listOf("a", "b") sumUp(strings)
  30. 48.

    fun sumUp(items: Collection<*>) {a if (items is List<Int>) {d println(ints.sum())

    }b }c val strings: List<String> = listOf("a", "b") sumUp(strings)
  31. 49.

    fun sumUp(items: Collection<*>) {a val ints = items as? List<Int>

    ?: return println("We got a list of ints") println(ints.sum()) }c val strings: List<String> = listOf("a", "b") sumUp(strings)
  32. 50.

    fun sumUp(items: Collection<*>) {a val ints = items as? List<Int>

    ?: return println("We got a list of ints") println(ints.sum()) }c val strings: List<String> = listOf("a", "b") sumUp(strings) ----- We got a list of ints Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
  33. 51.

    fun sumUp(items: Collection<*>) {a val ints = items as? List<Int>

    ?: return println("We got a list of ints") println(ints.sum()) }c val strings: List<String> = listOf("a", "b") sumUp(strings)
  34. 52.

    fun sumUp(items: Collection<Int>) {a val ints = items as? List<Int>

    ?: return println("We got a list of ints") println(ints.sum()) }c val strings: List<String> = listOf("a", "b") sumUp(strings)
  35. 53.
  36. 54.

    fun <T> Iterable<*>.filterIsInstance(): List<T> {a val destination = mutableListOf<T>() for

    (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f
  37. 55.

    fun <T> Iterable<*>.filterIsInstance(): List<T> {a val destination = mutableListOf<T>() for

    (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f listOf("a", 1, 0x0, 2L, 'u') .filterIsInstance<String>()
  38. 56.

    fun <T> Iterable<*>.filterIsInstance(): List<T> {a val destination = mutableListOf<T>() for

    (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f listOf("a", 1, 0x0, 2L, 'u') .filterIsInstance<Int>()
  39. 57.

    fun <T> Iterable<*>.filterIsInstance(): List<T> {a val destination = mutableListOf<T>() for

    (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f listOf("a", 1, 0x0, 2L, 'u') .filterIsInstance<Char>()
  40. 58.

    fun <T> Iterable<*>.filterIsInstance(): List<T> {a val destination = mutableListOf<T>() for

    (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f
  41. 59.
  42. 60.

    fun <T> Iterable<*>.filterIsInstance(): List<T> {a val destination = mutableListOf<T>() for

    (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f
  43. 61.

    inline fun <T> Iterable<*>.filterIsInstance(): List<T> {a val destination = mutableListOf<T>()

    for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f
  44. 62.

    inline fun <reified T> Iterable<*>.filterIsInstance(): List val destination = mutableListOf<T>()

    for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f
  45. 63.

    inline fun <reified T> Iterable<*>.filterIsInstance(): List val destination = mutableListOf<T>()

    for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f
  46. 64.

    inline fun <reified T> Iterable<*>.filterIsInstance(): List val destination = mutableListOf<T>()

    for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f listOf("a", 1, 0x0, 2L, 'u') .filterIsInstance<String>()
  47. 65.
  48. 69.
  49. 70.
  50. 71.
  51. 75.

    class CountingSet<T>( val innerSet: MutableCollection<T> = HashSet() ) : MutableCollection<T>

    {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection<T>): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t
  52. 76.

    class CountingSet<T>( val innerSet: MutableCollection<T> = HashSet() ) : MutableCollection<T>

    {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection<T>): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t
  53. 77.

    class CountingSet<T>( val innerSet: MutableCollection<T> = HashSet() ) : MutableCollection<T>

    {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection<T>): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k override val size: Int get() = innerSet.size override fun contains(element: T): Boolean { return innerSet.contains(element) } override fun containsAll(elements: Collection<T>): Boolean { return innerSet.containsAll(elements) } override fun isEmpty(): Boolean { return innerSet.isEmpty() } override fun clear() { innerSet.clear() } override fun iterator(): MutableIterator<T> { return innerSet.iterator() } override fun remove(element: T): Boolean { return innerSet.remove(element) } override fun removeAll(elements: Collection<T>): Boolean { return innerSet.removeAll(elements) } override fun retainAll(elements: Collection<T>): Boolean { return innerSet.retainAll(elements) } }t
  54. 78.

    class CountingSet<T>( val innerSet: MutableCollection<T> = HashSet() ) : MutableCollection<T>

    {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection<T>): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t
  55. 79.

    class CountingSet<T>( val innerSet: MutableCollection<T> = HashSet() ) : MutableCollection<T>

    by innerSet {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection<T>): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t
  56. 80.

    class CountingSet<T>( val innerSet: MutableCollection<T> = HashSet() ) : MutableCollection<T>

    by innerSet {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection<T>): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t
  57. 81.
  58. 82.

    class Foo { val data: Int by lazy { computeStuff()

    } } • lazy • observable • vetoable • notNull
  59. 85.

    assertThat(toString(taco)).isEqualTo("" + "package com.squareup.tacos\n" + "\n" + "import kotlin.String\n" +

    "\n" + "class Taco {\n" + " final override fun toString(): String = \"taco\"\n" + "}\n" + "")c
  60. 89.

    assertThat(toString(taco)).isEqualTo(""" |package com.squareup.tacos | |import kotlin.String | |class Taco {

    | final override fun toString(): String = "taco" |} |""".trimMargin())c
  61. 90.
  62. 97.
  63. 98.