Kotlin Scope Functions Explained: let vs run vs apply vs also vs with (Android Developer Cheat Sheet)

Introduction

If you’ve been writing Kotlin for Android, you’ve probably seen code like this:

user?.let { }

or

User().apply { }

Kotlin’s scope functions help developers write cleaner and more concise code, but many developers initially find them confusing.

Most developers eventually ask:

When should I use let, run, apply, also, or with?

In this guide, we’ll break down the differences between these functions and provide practical examples you can use in real Android projects.

👉 Korean Tip
코틀린을 처음 배울 때 많은 개발자들이 let / run / apply / also 차이에서 헷갈립니다.
하지만 객체 참조 방식(it vs this)리턴값만 이해하면 쉽게 구분할 수 있습니다.

 


Kotlin Scope Functions Overview

Kotlin provides five main scope functions:

  • let
  • run
  • apply
  • also
  • with

They mainly differ in two aspects:

1️⃣ How the object is referenced

Inside the lambda block, the object will be accessed as either:

  • it
  • this
     

2️⃣ What value the function returns

Some functions return the object itself, while others return the result of the lambda expression.

👉 Korean Tip
scope function을 이해할 때 가장 중요한 두 가지는 다음입니다.

  • 객체를 it으로 참조하는지 this로 참조하는지
  • 함수가 객체를 반환하는지 결과값을 반환하는지

Scope Functions Comparison Table

Here is a quick overview many developers keep as a reference.





Function

Object Reference

Returns

Typical Use

let

it

lambda result

null safety

run

this

lambda result

compute value

apply

this

object

object setup

also

it

object

logging / debugging

with

this

lambda result

operate on object

👉 Korean Tip
간단히 기억하는 방법

  • let → null 체크
  • run → 계산 결과 반환
  • apply → 객체 설정
  • also → 로그 / 디버깅
  • with → 객체 여러 작업 수행

Kotlin let Function

When to Use let

let is one of the most commonly used scope functions in Kotlin.

It is especially useful for null safety checks.

Example

val name: String? = "Android"

name?.let {

   println("Hello $it")

}

This code runs only when name is not null.

👉 Korean Tip
이 코드는 name 값이 null이 아닐 때만 실행됩니다.
그래서 let은 코틀린에서 null 처리할 때 가장 많이 사용하는 패턴입니다.

Practical Developer Tip

Instead of writing:

if (value != null) {

   process(value)

}

// You can simply write:

value?.let {

   process(it)

}

This keeps the code shorter and avoids nested conditions.

 


Kotlin run Function

run executes a block of code and returns the result of the lambda expression.

Example

val length = "Kotlin".run {

   println(this)

   length

}

Output:

Kotlin

Return value:

6

👉 Korean Tip
run객체를 사용해서 어떤 값을 계산할 때 자주 사용됩니다.

예를 들어 설정값을 계산하거나 결과값을 반환할 때 유용합니다.

Developer Insight

When accessing many properties of the same object, using this often makes the code easier to read than it.

 


Kotlin apply Function

apply is commonly used for object initialization.

It returns the object itself, which makes it perfect for configuring objects.

Example

data class User(

   var name: String = "",

   var age: Int = 0

)



val user = User().apply {

   name = "John"

   age = 25

}

👉 Korean Tip
apply객체를 생성하면서 속성을 설정할 때 가장 많이 사용됩니다.

Android UI 코드에서도 자주 등장합니다.

Example:

val button = Button(context).apply {

   text = "Click me"

   isEnabled = true

}

This keeps the UI setup code clean and readable.

 


Kotlin also Function

also is used when you want to perform side operations.

Typical examples include:

  • logging
  • debugging
  • analytics
     

Example

val numbers = mutableListOf(1,2,3)

numbers.also {

   println("Before adding item: $it")

}.add(4)

👉 Korean Tip
also객체를 변경하지 않고 중간에 로그를 찍거나 확인할 때 유용합니다.

Developer Tip

also is great when debugging method chains.

Example:

data

   .also { println("Loaded data: $it") }

   .process()

This allows you to inspect the value without breaking the chain.

 


Kotlin with Function

with is slightly different because it is not an extension function.

Instead, the object is passed as a parameter.

Example

val result = with(StringBuilder()) {

   append("Hello ")

   append("Kotlin")

   toString()

}

Output

Hello Kotlin

👉 Korean Tip
with같은 객체를 여러 번 사용할 때 코드 반복을 줄여줍니다.

 


Common Mistakes Developers Make

Confusing apply and also

Many beginners mix these two.

Simple rule:

  • apply → configure object
     
  • also → side effects
     

👉 Korean Tip
apply는 객체 설정, also는 로그나 디버깅이라고 기억하면 쉽습니다.

 


Overusing Scope Functions

Using too many nested scope functions can reduce readability.

Example:

user?.let {

   it.run {

       also {

           println(it)

       }

   }

}

Most experienced developers would simplify this.

👉 Korean Tip
scope function은 코드를 더 읽기 쉽게 만들 때만 사용하는 것이 좋습니다.

 


Best Practices

Use let for null checks

value?.let { }

Use apply for initialization

val user = User().apply { }

Use also for logging

object.also { println(it) }

👉 Korean Tip
scope function은 짧고 읽기 쉽게 사용할 때 가장 효과적입니다.

 


Quick Cheat Sheet





Function

Reference

Returns

Best For

let

it

lambda result

null checks

run

this

lambda result

computing values

apply

this

object

object configuration

also

it

object

logging

with

this

lambda result

object operations

 


FAQ

What is the difference between let and run?

Both return the lambda result.

The main difference is:

  • let uses it
     
  • run uses this
     

Which scope function should beginners learn first?

Most developers start with:

  • let
     
  • apply
     

because they solve common problems like null safety and object initialization.

👉 Korean Tip
코틀린 초보라면 let과 apply를 먼저 익히는 것이 좋습니다.

 

heejin's picture

Language

Get in touch with us

"If you would thoroughly know anything, teach it to other."
- Tryon Edwards -