Slide 1

Slide 1 text

Lambda with receiver

Slide 2

Slide 2 text

Extension Function & Lambda Lambda with receiver

Slide 3

Slide 3 text

val sb = StringBuilder()
 with (sb) {
 appendln("Alphabet: ")
 for (c in 'a'..'z') {
 append(c)
 } toString()
 } The with function with is a function val sb = StringBuilder()
 sb.appendln("Alphabet: ")
 for (c in 'a'..'z') {
 sb.append(c)
 }
 sb.toString()


Slide 4

Slide 4 text

lambda is its second argument val sb = StringBuilder()
 with (sb) {
 this.appendln(“Alphabet: ")
 for (c in 'a'..'z') {
 this.append(c)
 } this.toString()
 } val sb = StringBuilder()
 with (sb, { ->
 this.appendln(“Alphabet: ")
 for (c in 'a'..'z') {
 this.append(c)
 } this.toString()
 }) lambda is its second argument Lambda with receiver with is a function this is an implicit receiver in the lambda val sb = StringBuilder()
 with (sb) {
 appendln("Alphabet: ")
 for (c in 'a'..'z') {
 append(c)
 } toString()
 } this can be omitted

Slide 5

Slide 5 text

Lambda with receiver val sb = StringBuilder()
 with (sb) {
 appendln("Alphabet: ")
 for (c in 'a'..'z') {
 this.append(c)
 } } lambda with implicit this

Slide 6

Slide 6 text

regular function regular lambda extension function lambda with receiver Extension function vs lambda with receiver

Slide 7

Slide 7 text

regular function regular lambda extension function lambda with receiver fun String.lastChar() = this.get(this.length - 1) buildString { this.append("...") } Extension function vs lambda with receiver

Slide 8

Slide 8 text

regular function regular lambda extension function lambda with receiver Lambda vs lambda with receiver val isEven: (Int) -> Boolean = { it % 2 == 0 } val isOdd: Int.() -> Boolean = { this % 2 == 1 } isEven(0) 1.isOdd() calling as regular function calling as extension function

Slide 9

Slide 9 text

val s: String = buildString {
 appendln("Alphabet: ")
 for (c in 'a'..'z') {
 append(c)
 }
 } Another example: buildString lambda with receiver

Slide 10

Slide 10 text

buildString { this.append("...") } inline fun buildString( builderAction: StringBuilder.() -> Unit ): String { val stringBuilder = StringBuilder() ... return stringBuilder.toString() } The buildString function Creates a StringBuilder Calls the specified actions on a stringBuilder Returns String as a result stringBuilder.builderAction()

Slide 11

Slide 11 text

with (sb) {
 appendln("Alphabet: ")
 ...
 } inline fun with( receiver: T, block: T.() -> R ): R = receiver.block() The with function declaration

Slide 12

Slide 12 text

val db: SQLiteDatabase = … db.beginTransaction()
 try {
 db.delete("users", "first_name = ?", arrayOf("Jake"))
 db.setTransactionSuccessful()
 } finally {
 db.endTransaction()
 } db.inTransaction {
 delete("users", "first_name = ?", arrayOf("Jake"))
 } Avoiding Duplication

Slide 13

Slide 13 text

db.beginTransaction()
 try {
 db.delete("users", "first_name = ?", arrayOf("Jake"))
 db.setTransactionSuccessful()
 } finally {
 db.endTransaction()
 } db.inTransaction {
 delete("users", "first_name = ?", arrayOf("Jake"))
 } Inline functions is declared as inline function generated bytecode is similar to

Slide 14

Slide 14 text

html {
 table {
 for (product in products) {
 tr {
 td { text(product.description) }
 td { text(product.price) }
 td { text(product.popularity) }
 }
 }
 }
 } HTML Builders lambdas with receiver

Slide 15

Slide 15 text

Anko Layouts DSL for dynamic layouts

Slide 16

Slide 16 text

Alerts fun Activity.showAreYouSureAlert(process: () -> Unit) {
 alert(title = "Are you sure?",
 message = "Are you really sure?") {
 positiveButton("Yes") { process() }
 negativeButton("No") { }
 }.show()
 } Are you sure? Are you really sure? No Yes

Slide 17

Slide 17 text

customView {
 verticalLayout {
 val email = editText {
 hint = "Email"
 }
 
 val password = editText {
 hint = "Password"
 transformationMethod = PasswordTransformationMethod.getInstance()
 }
 
 positiveButton("Log In") {
 logIn(email.text, password.text)
 }
 }
 } Password Log In Email Custom layouts

Slide 18

Slide 18 text

plugins { application kotlin("jvm") version "1.1.51" } application { mainClassName = "samples.HelloWorldKt" } dependencies { compile(kotlin("stdlib")) } repositories { jcenter() } Gradle Build Script in Kotlin

Slide 19

Slide 19 text

More useful library functions inline fun with(receiver: T, block: T.() -> R): R = receiver.block() inline fun T.run(block: T.() -> R): R = block() inline fun T.let(block: (T) -> R): R = block(this) inline fun T.apply(block: T.() -> Unit): T { block(); return this } inline fun T.also(block: (T) -> Unit): T { block(this); return this }

Slide 20

Slide 20 text

with with (window) { width = 300 height = 200 isVisible = true } inline fun with(receiver: T, block: T.() -> R): R = receiver.block()

Slide 21

Slide 21 text

run: like with, but extension val windowOrNull = windowById["main"] windowOrNull?.run { width = 300 height = 200 isVisible = true } inline fun T.run(block: T.() -> R): R = block()

Slide 22

Slide 22 text

run: like with, but extension windowById["main"]?.run { width = 300 height = 200 isVisible = true } inline fun T.run(block: T.() -> R): R = block()

Slide 23

Slide 23 text

apply: returns receiver as a result val mainWindow = windowById["main"]?.apply { width = 300 height = 200 isVisible = true } ?: return inline fun T.apply(block: T.() -> Unit): T { this.block(); return this }

Slide 24

Slide 24 text

also: regular argument instead of this inline fun T.also(block: (T) -> Unit): T { block(this); return this } windowById["main"]?.apply { width = 300 height = 200 isVisible = true }?.also { showWindow(it) }

Slide 25

Slide 25 text

{ .. this .. } { .. it .. } return result of lambda run let return receiver apply also receiver.apply { this.actions() } receiver.also { moreActions(it) }

Slide 26

Slide 26 text

Copyright © 2017 https://github.com/JetBrains/kotlin-workshop