ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kotlin 코틀린] Scope function - apply, with, let, also ,run
    Kotlin 2021. 8. 28. 23:11
    728x90

    Scope Function

    Kotlin 표준 라이브러리에는 제공된 람다 식이 있는 object 에서 scope function 을 호출하면 임시 범위가 형성된다. 이 범위에서는 이름 없이 object 에 액세스할 수 있다. 코드를 더 간결하고 읽기 쉽게 만들 수 있다.

     

    Function 개체 참조 (Object reference) 반환 값 (Return value) 확장 기능 여부 (Is extension function)
    let it Lambda result
    run this Lambda result
    run - Lambda result 아니오 : Context object 없이 호출
    with this Lambda result 아니오 : Context object 를 인수로 사용
    apply this Context Object
    also it Context Object

    Scope Function 에는 두 가지 주요 차이점이 있다.

     

    Context Object  참조

    • this : run, with, apply 는 Context Object 를 lambda receiver 인 'this' 로 참조한다. 따라서 람다식 안에서는 일반 클래스 멤버처럼 사용할 수 있다.
    val adam = Person("Adam").apply { 
        age = 20                       // same as this.age = 20 or adam.age = 20
        city = "London"
    }
    println(adam)
    • it : let, also 는 lambda argument 처럼 'it' 으로 참조한다. 따로 전달 인자명을 지정할 수도 있고, 지정하지 않으면 기본적으로 'it' 으로 접근한다. 하지만 'this' 처럼 object 의 함수나 프로퍼티를 호출할 때 'this' 처럼 암시적으로 사용할 수 는 없다.
    fun getRandomInt(): Int {
        return Random.nextInt(100).also {
            writeToLog("getRandomInt() generated value $it")
        }
    }
    
    val i = getRandomInt()

     

    Return value

    • Context Object : apply 와 also 는 코드 블록의 context object 를 반환한다. 따라서 같은 객체에 대한 call chain 을 가질 수 있고, return 문에 사용될 수 있다.
    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()
    • Lambda result : let, run, with 은 lambda result 를 반환한다. 추가적으로 이 return value 를 무시하고 변수를 위한 일시 범위를 생성하는데 사용할 수도 있다.
    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
    }

     


    let

    • it / lambda result
    • call chains 의 결과 값에 하나 이상의 함수를 호출할 때 사용한다.
    val numbers = mutableListOf("one", "two", "three", "four", "five")
    numbers.map { it.length }.filter { it > 3 }.let { 
        println(it)
    } 
    
    val numbers = mutableListOf("one", "two", "three", "four", "five")
    numbers.map { it.length }.filter { it > 3 }.let(::println)
    
    // [5, 4, 4]
    • ?. 를 사용하여 non-null 값일 때만 코드 블록을 실행시킬 때 자주 사용된다.

     

    with

    • this / lambda result / 인자로 context object 전달
    • lambda result 반환 없이 코드 블록 내에서 함수를 호출할 때 사용할 것을 추천
    • " with this object, do the following."
    val numbers = mutableListOf("one", "two", "three")
    with(numbers) {
        println("'with' is called with argument $this")
        println("It contains $size elements")
    }

     

    run

    • this / lambda result / with 과 동일하지만 context object 의 확장함수로 호출
    • 코드 블록 내에 객체 초기화와 반환 값 계산을 둘다 담고 있는 경우에 유용하다.
    val service = MultiportService("https://example.kotlinlang.org", 80)
    
    val result = service.run {
        port = 8080
        query(prepareRequest() + " to port $port")
    }
    
    // the same code written with let() function:
    val letResult = service.let {
        it.port = 8080
        it.query(it.prepareRequest() + " to port ${it.port}")
    }

     

    apply

    • this / context object
    • 주로 객체 초기화 시에 많이 사용된다.
    • " apply the following assignments to the object." 
    val adam = Person("Adam").apply {
        age = 32
        city = "London"        
    }
    println(adam)

     

    also

    • it / context object
    • context object 를 인자처럼 사용하는 액션에 유용하다.
    • object 의 프로퍼티나 함수에 대한 참조가 아닌 object 자체에 대한 참조가 필요한 액션에 유용하다.
    val numbers = mutableListOf("one", "two", "three")
    numbers
        .also { println("The list elements before adding new one: $it") }
        .add("four")

     

     

    https://kotlinlang.org/docs/scope-functions.html

     

    728x90
Designed by Tistory.