[Kotlin] Scope Function

Subeen·2023년 12월 21일
0

Kotlin 문법

목록 보기
21/23

Scope Function

  • Kotlin 표준 라이브러리에는 객체 내에서 코드 블록을 실행하는 것이 유일한 목적인 여러 함수가 포함되어 있다.
  • 제공 되는 람다식이 있는 개체에서 이러한 함수를 호출하면 임시 범위(Scope)가 형성 된다.
  • 이 범위에서는 이름 없이 개체에 접근할 수 있으며 이러한 함수를 Scope Function 이라고 한다.

Scope Function 종류

  • Scope Function에는 let, run, with, apply, also가 있다.
FunctionObject referenceReturn valueIs extension function
letitLambda resultYes
runthisLambda resultYes
run-Lambda resultNo: context 개체 없이 호출됨
withthisLambda resultNo: Context 개체를 인수로 사용함
applythisContext objectYes
alsoitContext objectYes

어떤 상황에 어떤 함수를 써야하는지 정확히 이해하지 못하고 매번 헷갈렸는데 이 그림을 외워야할 것 같다..😅

let

함수객체 참조반환 값확장 함수
letitLambda resultYes
  • let은 extension function이며 반환 값이 Lamda result이다.
  • 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있다.
  • 객체를 생성하거나 사용하는 시점에서 이름을 부여하여 다양한 작업을 수행시키고 결과를 돌려받고 싶을 때 유용하다.
    // let을 사용하지 않는 경우
    val numbers = mutableListOf("one", "two", "three", "four", "five")
    val resultList = numbers.map { it.length }.filter { it > 3 }
    println(resultList)  // [5, 4, 4]

    // let을 사용하는 경우
    val letNumbers = mutableListOf("one", "two", "three", "four", "five")
    letNumbers.map { it.length }.filter { it > 3 }.let {
        println(it)  // [5, 4, 4]
    }
	// let은 null이 아닌 값을 포함하는 코드 블록을 실행하는 데 자주 사용 된다.
    val str: String? = "Hello"
    val length = str?.let {
        println("let() called on $it")  // let() called on Hello
        it.length
    }
    val numbers = listOf("one", "two", "three", "four")
    val modifiedFirstItem = numbers.first().let { firstItem ->
        println("첫번째 요소 '$firstItem'")  // 첫번째 요소 'one'
        if (firstItem.length >= 5) firstItem else "!$firstItem!"
    }.uppercase()
    println("수정 후 첫 번째 요소: '$modifiedFirstItem'")  // 수정 후 첫 번째 요소: '!ONE!'

run

함수객체 참조반환 값확장 함수
runthisLambda resultYes
run-Lambda resultNo: context 개체 없이 호출됨
  • run은 단일 Lamda function을 인자로 받는 버전과 extension function으로 이루어진 버전이 있다.
  • 두 개 모두 반환 값은 Lamda result이며 임의로 생성한 값이나 객체를 반환할 수 있다.
  • 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있다.
  • 객체를 생성하거나 사용하는 시점에서 다양한 작업을 수행시킨 후 결과를 반환 받고 싶을 때 유용하다.
class MultiportService(var url: String, var port: Int) {
    fun prepareRequest(): String = "Default request"
    fun query(request: String): String = "Result for query '$request'"
}

fun main() {
    val service = MultiportService("https://example.kotlinlang.org", 80)

    val result = service.run {
        port = 8080
        query(prepareRequest() + " to port $port")
    }
    println(result)  // Result for query 'Default request to port 8080'
}
    val adam = Person("Adam", 32, "London")
    val nextAge = adam.run {
        ++age
    }
    println(nextAge)  // 33

with

함수객체 참조반환 값확장 함수
withthisLambda resultNo: Context 개체를 인수로 사용함
  • with는 extenstion function이 아니며 객체를 argument로 받아 사용한다.
  • 두 번째 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있으며 반환 값은 Lamda result이다.
  • with는 이미 생성된 객체에 일괄적인 작업을 처리할 때 유용하다.
    val numbers = mutableListOf("one", "two", "three")
    with(numbers) {
        val firstItem = first()
        val lastItem = last()
        println("First item: $firstItem, last item: $lastItem")  
        // First item: one, last item: three
    }
    val numbers = mutableListOf("one", "two", "three")
    with(numbers) {
        println("'with' 는 ${this} 로 참조합니다.")
        println("${size}개의 요소를 포함합니다.")
    }
    /*
    'with' 는 [one, two, three] 로 참조합니다.
    3개의 요소를 포함합니다.
     */

run과 with의 차이점

run과 with는 유사하지만 run은 extension function 버전으로 인해 객체를 생성해서 할당하기 전에 사용이 가능하다는 차이가 있다.

apply

함수객체 참조반환 값확장 함수
applythisContext objectYes
  • apply extension function이며 반환 값이 Context object이다.
  • 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있다.
  • 객체에 무언가를 적용(apply)할 때객체 생성시점에 초기화를 할 때 유용하다.
data class Person(var name: String, var age: Int = 0, var city: String = "")

fun main() {
	// apply를 사용하는 경우
    val adam = Person("Adam").apply {
        age = 32
        city = "London"
    }
    println(adam)  // Person(name=Adam, age=32, city=London)
}
	// apply를 사용하지 않는 경우 
    val adam = Person("Adam")
    adam.age = 32
    adam.city = "London"

also

함수객체 참조반환 값확장 함수
alsoitContext objectYes
  • also는 extension function이며 반환 값이 Context object이다.
  • 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있다.
  • 객체에게 명령을 내리기 직전에 추가적인(also) 작업을 함께 수행시키고 싶을 때 유용하다.
    val numbers = mutableListOf("one", "two", "three")
    numbers
        .also { println("$it") }  // [one, two, three]
        .add("four")

apply와 also의 차이점

apply와 also는 유사하지만 applyLamda funtion에 인자를 넘겨주지 않기 때문this를 이용해 참조한다.
그에 반해 alsoLamda function에 인자를 넘겨주기 때문에 인자를 it이나 다른 이름을 부여해 참조가 가능하다.

참조
코틀린(Kotlin)의 Scope Function(let, with, run, apply, also) 정리
Kotlin Scope function 올바르게 사용하기
Scope Function

profile
개발 공부 기록 🌱

0개의 댓글