스코프 함수

Minsuk Jang·2021년 11월 16일
0

코틀린

목록 보기
4/4
post-thumbnail

스코프 함수에 대해 알아보자

🤔 스코프 함수란?

  • Scope function(let, with, run, apply, also)를 이용하게 되면 일시적으로 Scope가 생기고 이 범위 안에서는 전달된 객체를 it or this라는 Context Object에 접근하게 된다.

  • with, also, run, apply, let 의 스코프 함수는 동일한 역할을 수행하지만 차이점이 존재한다.

👏 사용 목적

  • 코드를 좀 더 간결하고 읽기 쉽게 만들어주기 위함

run (this)

  • 람다 함수의 반환 값
  • 객체 초기화와 반환값 계산에 유용하게 사용한다.

람다 함수의 반환 값

run() 함수의 코드 스니핏

매개변수 block: T.() -> R 에서 -> 를 기준으로 우측에 있는 값(R) 은 함수의 반환값을 뜻한다. 람다 함수는 return을 명시하지 않고 맨 마지막 값이 반환값을 뜻한다.

따라서, run() 함수도 block 반환하는 값과 동일한 자료형 R 을 반환하기에 block이 반환하는 값을 얻을 수 있다.

run() 함수는 람다 함수의 맨 마지막 값이 반환 값이 된다.

fun main (args : Array<String>){
    val result = User().run {
        printName()
        printAge()

        age = 30
        "Run Return Result"
    }

    println("Result: $result")
}

class User{
    var name : String = "jms8732"
    var age : Int = 10


    fun printName(){
        println("Name: $name")
    }

    fun printAge(){
        println("Age: $age")
    }
}

간단한 run() 에 관련된 예제이다.
코드를 돌려보면 알 수 있듯 Result은 "Run Return Result"를 출력한다.


apply (this)

  • Object configuration 를 할 때, 주로 사용한다.
  • 반환 값은 객체 이다.
  • run() 함수와 차이나는 부분은 반환 값이다.
apply() 함수 코드 스니핏

반환값을 보면 run() 함수와 다르게 객체 (this) 자체를 반환하는 것을 알 수 있다.

fun main(args : Array<String>){
    val result = User().apply {
        printAge()
        printName()

        age = 20
    }

    println("Result: $result")
}

result는 User 객체인 것을 확인할 수 있다.


with (this)

  • 반환 값은 람다 결과 값 이다.
  • 람다 결과값을 사용하지 않고 Context에 대한 함수 호출할 때 사용
  • null 안전성을 지원하지 않음
  • run() 함수는 자신을 호출한 객체를 이용하지만 with() 함수는 매개변수로 지정된 객체를 이용
with 코드 스니핏
fun main(args : Array<String>){
    val user = User()

    val result = with(user){
        printAge()
        printName()

        3 + 4
    }

    println("Result: $result")
}

Result의 값은 7이 출력되는 것을 알 수 있다.


let (it)

  • 반환 값은 람다 결과 값 이다.
  • non-null value를 이용하기 위해 종종 사용한다.
  • 제한된 scope 내에서 지역 변수를 사용하는 것
  • 객체 결과 값에 하나 이상의 함수를 호출할 때 사용한다.
let() 함수의 코드 스니핏

run() 함수처럼 람다 함수의 결과값을 반환하지만 Context를 참조하기 위해 this 대신 it을 사용한다.

fun main(args: Array<String>) {
    val result = User().apply {
        age = 25
        name = "james"
    }.let {
        letPrintlnTest(it)
        letPrintlnTest1(it)
        3 + 4
    }

    println("Result: $result")
}

fun letPrintlnTest(user: User) {
    println("User info: ${user.name}, ${user.age}")
}

fun letPrintlnTest1(user : User){
    println("User info1: ${user.name}, ${user.age}")
}

let() 함수를 사용하는 방법을 살펴보면 객체를 설정한다기 보다는 객체를 사용한다는 것에 초점이 있는 느낌이 들었다.


also (it)

  • 반환값은 객체 이다.
  • let() 함수와 유사한 동작을 하나 반환 값이 다르다.
also 코드 스니핏
fun main(args : Array<String>){
    val user = User().also {
        it.printAge()
        it.printName()
    }

    println("User: $user")
}

✔ 정리

추후 takeif / takeUnless 추가

👍 참조

profile
Positive Thinking

0개의 댓글