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

Kotlin's Advanced Language Features

Kotlin's Advanced Language Features

Avatar for Benoît Quenaudon

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