Skip to content

Instantly share code, notes, and snippets.

@pokk
Last active November 9, 2020 11:14
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pokk/0f9649e6f0855548997f0ed0b42106e9 to your computer and use it in GitHub Desktop.
Save pokk/0f9649e6f0855548997f0ed0b42106e9 to your computer and use it in GitHub Desktop.
Kotlin stdlib "let", "run", "apply", "also", "use", "with"

[TOC]

Introduction

There are very good five stdlib operates we can use.

  1. let
  2. run
  3. apply
  4. also
  5. use
  6. with

All of them are very interesting and useful!!

Comparison

Connect Type Parameter Return Enviroment Comment
let extended function it last line 1. Check null pointer
2. Unwrap nullable variable
run extended function
ordinary function
this last line 1. Block context
2. Real useful operator
You can image that "run" is "let"
without parameter basically.
also extended function it called object 1. Builder setting
2. Context switch
apply extended function this called object 1. Builder setting
2. Context switch
use extended function it last line 1. try-with-resource
with extended function this last line with(x) and x.apply are almost same.
"with" can't use chain pattern and return difference date type.

From Kotlin 1.1

also is the same as apply, just, also's parameter was changed to it.

Example

let

// 1. Check null pointer.
var prefs: Preferenens? = getSharedPreferences()
prefs?.let {
    // This whole block will not be executed if "prefs" is null.
    // Additionally, "it" has now been cast to a "Preferenens".
    it.putString("name", "Jieyi")
    it.commit()
}
// Oppsite is when prefs is null
prefs?:let {
    // What thing you should handle.
}

// 2. Unwrap null-safe
val filePath: String? = null
val drawable: Drawable = filePath?.let {
    // This block is null-safe.
    BitmapDrawable.createFromPath(it)
} ?: ColorDrawable(Color.TRANSPARENT)

run

fun max(numbers: Array<Int>?): Int = numbers?.run {
    var max: Int? = null
    forEach { max = Math.max(it, max) }
    return max ?: 0
} ?: 0

fun max(numbers: Array<Int>?): Int = numbers.orEmpty().run {
    var max: Int? = null
    forEach { max = Math.max(it, max) }
    return max ?: 0
}

apply & also

Basically, apply & also are the same. But inside of the block, this and it are used by apply and also.

// 1. As like a builder to be used.
val view: View = View(this).apply {
    this.background = ColorDrawable(Color.TRANSPARENT)
    this.alpha = 1f
    this.isClickable = true
}
// also is from kotlin 1.1
val view: View = View(this).also {
    it.background = ColorDrawable(Color.TRANSPARENT)
    it.alpha = 1f
    it.isClickable = true
}

// 2. Context switch.
class ExampleUnitTest {
    @Test fun addition_isCorrect() {
        ColorDrawable(Color.RED).apply {
            // Check "this" is Drawable.
            assert(this is Drawable)
        }
    }
}

use

// 1. Write a file.
File("somefile.txt").bufferedWriter().use { out ->
    history.forEach {
        out.write("${it.key}, ${it.value}\n")
    }
}

// Other example.
val prop = Properties()
FileInputStream("config.properties").use {
    prop.load(it)
}
// FileInputStream automatically closed

with

val w = Window()
with(w) {
  setWidth(100)
  setHeight(200)
  setBackground(RED)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment