TIL

Scope function

코틀린 스코프 함수 (Scope Functions)

주요 스코프 함수

Function Object reference Return value Is extension function
let it 람다 결과 O
run this 람다 결과 O
run - 람다 결과 No: called without the context object
with this 람다 결과 No: takes the context object as an argument.
apply this Context object O
also it Context object O

Distinctions

컨텍스트 접근 방식

val adam = Person("Adam").apply { 
    age = 20 
    city = "London"
}
fun getRandomInt(): Int {
    return Random.nextInt(100).also {
        writeToLog("getRandomInt() generated value $it")
    }
}

Return value

// 반환된 객체를 이어서 체이닝 할 수 있다.
val numberList = mutableListOf<Double>()
numberList.also { println("Populating the list") }
    .apply {
        add(2.71)
        add(3.14)
        add(1.0)
    }
    .also { println("Sorting the list") }
    .sort()
    
// 함수에서 해당 객체를 직접 반환할 때 유용하다.
fun getRandomInt(): Int {
    return Random.nextInt(100).also {
        writeToLog("getRandomInt() generated value $it")
    }
}
val numbers = mutableListOf("one", "two", "three")

// 결과를 변수로 할당하거나 결과를 바탕으로 연산을 이어갈 때 적합
val countEndsWithE = numbers.run { 
    add("four")
    add("five")
    count { it.endsWith("e") }
}

// 반환값이 필요 없다면 단순 임시 스코프를 만들기 위해 사용할 수도 있다.
with(numbers) {
    val firstItem = first()
    val lastItem = last()        
    println("First item: $firstItem, last item: $lastItem")
}

Functions

let

val numbers = mutableListOf("one", "two", "three", "four", "five")

// 호출 체인의 결과에 여러 동작을 수행할 때
val resultList = numbers.map { it.length }.filter { it > 3 }

// null 체크 후 안전하게 사용
val firstOrNull = numbers.firstOrNull()?.let {
    println("첫 번째 원소: $it")
}

// 임시 변수 범위 제한
val result = numbers.map { it.length }.filter { it > 3 }.let { lengths ->
    lengths.sum()
}

with

val builder = StringBuilder()
with(builder) {
    append("Hello, ")
    append("Kotlin!")
    toString()
}

run

val message = StringBuilder().run {
    append("Kotlin Scope Functions. ")
    append("run 예제")
    toString()
}

apply

val person = Person().apply {
    name = "홍길동"
    age = 30
}

also

val numbers = mutableListOf("one", "two", "three")
numbers
    .also { println("초기 값: $it") }
    .add("four")

takeIf / takeUnless

val number = 10
val even = number.takeIf { it % 2 == 0 }   // 10
val odd = number.takeUnless { it % 2 == 0 } // null