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

Kotlin's Advanced Language Features

Kotlin's Advanced Language Features

Benoît Quenaudon

October 18, 2018
Tweet

More Decks by Benoît Quenaudon

Other Decks in Programming

Transcript

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

    sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array<String>) {c }e
  2. 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. 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. 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. 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. 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. 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. 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. 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. fun <T, R> with( receiver: T, block: T.() -> R

    ): R { return receiver.block() }
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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. 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
  21. 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
  22. fun requireNotNull(obj: Any?) {a if (obj == null) throw IllegalArgumentException()

    }d fun foo(s: String?) {e requireNotNull(s) s.length }f
  23. 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
  24. people // List<People> .asSequence() // Sequence<People> .map(People::name) // Sequence<String> .filter

    { it.startsWith("J") } // Sequence<String> .toList() // List<People>
  25. 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)
  26. 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)
  27. 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)
  28. 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
  29. 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)
  30. 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)
  31. 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
  32. 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>()
  33. 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>()
  34. 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>()
  35. 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
  36. 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. 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
  38. 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
  39. 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
  40. 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>()
  41. 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
  42. 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
  43. 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
  44. 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
  45. 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
  46. 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
  47. class Foo { val data: Int by lazy { computeStuff()

    } } • lazy • observable • vetoable • notNull
  48. 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
  49. assertThat(toString(taco)).isEqualTo(""" |package com.squareup.tacos | |import kotlin.String | |class Taco {

    | final override fun toString(): String = "taco" |} |""".trimMargin())c