본문 바로가기

[Kotlin] 코틀린 Scope Functions(let, apply, run, with, also) 알아보기

꿈꾸는블로그왕 2020. 11. 11.

let, apply , run, with, also를 언제써야 할 지 헷갈리때가 많습니다.

코틀린을 더 코틀린 답게 쓰기 위해서 위 함수들의 사용법에 익숙해 져야 합니다.

 

그래서 오늘은 Scope Function 대해서 정리해 보겠습니다.

 

Scope Function 을 구분하려면 아래 두가지 차이점을 알아야 합니다.

 

1. Context object를 참조하는방식: this 또는 it

2. Return value: context object 또는 lambda result

 

함수 참조 방식 리턴 값
with() this Unit
apply() this context object
also() it context object
let() it lambda result
run() this lambda result

 

그러면 함수별로 차이점을 알아보겠습니다.

 

with() 함수

- Context object: this

- Return value: lambda result

 

인자로 받은 객체를 람다식의 Receiver로 전달합니다.

with()함수는 safe call을 지원하지 않기 때문에 Non-null 객체에서만 사용합니다.

이때문에 보통 let()함수와 같이 사용하기도 합니다. ?.let { with(it)... }

class Student {
    var name: String? = "James"
    var age: Int? = 12
}

fun main() {
    val student = Student()

    with(student) {
        println(this.name)
        println(this.age)
    }
}

Student() 객체를 생성한 후에 with() 함수의 인자로 전달하면 this를 통해서 접근해서 사용할 수 있습니다.

this는 생략가능합니다.

 

 

apply() 함수

- Context object: this

- Return value: context object

호출하는 객체를 람다식에 전달하고 객체 자체를 반환합니다.

class Student {
    var name: String? = "James"
    var age: Int? = 12
}

fun main() {
    val student = Student().apply {
        name = "Bond"
        age = 45
    }

    with(student) {
        println(name)
        println(age)
    }
}

객체를 생성하는 동시에 apply()를 사용하여 name, age를 변경했습니다.

apply()함수는 객체 자체를 반환하기 때문에 반환된 객체가 student에 할당 됩니다.

 

 

 

 

also() 함수

- Context object: it

- Return value: context object

호출하는 객체를 람다식에 전달하고 객체 자체를 반환합니다.

fun main() {
    val capitalList: MutableList<String> = mutableListOf("Seoul", "Tokyo", "New York")

    capitalList.also {
        it.add("Beijing")
        it.remove("Seoul")
    }

    println(capitalList)
}

apply()함수와의 차이점은 also()함수는 it을 통해 접근할 수 있다는 점입니다.

 

 

let() 함수

- Context object: it

- Return value: lambda result

호출하는 객체를 람다식에 전달하고 결과를 반환합니다.

fun main() {
    var studentName: String? = null

    studentName?.let {
        println(it.capitalize())
        println(it.reversed())
        println(it.length)
    }

    studentName = "James"

    val stringLength = studentName.let {
        println(it.capitalize())
        println(it.reversed())
        it.length
    }

    println(stringLength)
}

studentName은 널이 가능한 변수입니다.

let()함수는 safe call을 사용하여 null이 아닐 경우 자신의 값을 it으로 받아서 처리할 수 있습니다. 

 

 

run() 함수

- Context object: this

- Return value: lambda result

인자가 없는 익명함수 형태와 객체에서 호출하는 형태가 있습니다.

with()함수는 let과 with를 합친 형태로 널이 가능한 객체에서 사용하 실 수 있습니다.

class Dog {
    var name: String? = "Happy"
    var age: Int? = 0
}

fun main() {
    val dog: Dog? = Dog()

    val intResult = dog?.run {
        println(name)
        println(age)
        age?.plus(5)
    }

    println(intResult)

    val stringResult = dog?.run {
        println(name)
        println(age)
        age?.plus(5)
        "This is the result!"
    }

    println(stringResult)
}

run() 함수는 람다식의 마지막 값을 리턴합니다.

 

 

댓글