본문 바로가기

안드로이드/알아두기

[안드로이드] let, run 등에 대하여

코틀린으로 안드로이드를 개발하다보면 누구나 쉽게 let, run, also, apply, with 등과 같은 객체를 본적이 있을 것이다.

여기서 내가 궁금한거는 그래 쓰면 편하긴 한데, 대관절 이것들을 어느 시점에서 어떤걸 써야 하는지가 궁금하다.

그래서 그거에 대하여 정리를 해 볼 것이다.

 

여러 사이트를 쭈욱 봤을 때, 이러니 저러니 좋은 설명들이 많다. 다만 와닿게 나는 그냥 심플하게 적어둔다.

 

1. apply

apply는 apply가 받는 객체에 대하여 해당 객체의 내부에서 그 객체의 함수를 사용하지 않는다면 사용이 적합하다. 아주 간단하게 설명하자면, 객체 초기화 할 때 쓰자.

    data class PersonInformation(
        var name : String = "",
        var age : Int = 0
    )

    class test(){
        fun temp(){
            var person = PersonInformation()
            person.apply{
                it.name = "Uni"
                it.age = 30
            }
        }
    }

 

2. also

also의 경우에는 apply와 마찬가지로 수신 객체를 반환한다. 다만 수신 객체의 속성을 변경하지 않고 사용하는 경우에는 also가 편하다. 이것도 간단하게 얘기하자면, 수신 받는 객체의 프로퍼티 데이터가 유효한지 유효성 검사를 할 때 아주 유용하다. 아래와 같이 말이다.

    data class PersonInformation(
        var name : String = "",
        var age : Int = 0
    )

    class test(){
        fun temp(){
            val person = PersonInformation()
            
            person.also{
                checkNotNull(it.name)
            }
        }
    }

 

3. let

let은 간단하다. let이 지정된 객체null 값인지 확인하고, null이 아니라면 let 안에 있는 코드를 실행해주는 것이다. 그래서 일반적으로 ?와 같이 사용된다. 만약 해당 객체가 NotNull이 보장된다면 그냥 ? 없이 사용해도 괜찮다.

    data class PersonInformation(
        var name : String?,
        var age : Int = 0
    )

    class test(){
        fun temp(){
            val person = PersonInformation()
            
            person.name?.let{
            // name이 null값이 아니면 코드가 실행된다.    
            }
        }
    }

 

4. with

with는 다른 것들과 달리 '.'을 통하여 수신객체를 받는게 아니라 소괄호를 이용하여 파라미터 값으로 객체를 받는다. 그리고 그 객체는 Non-nullable 수신 객체이다. 또한 해당 객체에 대한 결과가 필요하지 않는 경우에만 with을 사용한다. 쉽게 말하자면, 어디다가 쓰는지 모르겠다. 아마 별로 쓸일은 없지 않을까 싶다.

 

5. run

run의 경우에는 특정 값에 대한 계산이 필요하거나 여러개의 지역 변수의 범위를 제한하는데 사용하기에 용이하다. 아래와 같은 코드에서 지역변수의 범위를 제한하기도 하고, person 자체를 수신객체로 변환해서 사용되기도 한다.

//GM.Lim 님의 블로그 중 run 사용 규칙 example 발췌
val inserted: Boolean = run {
    // person 과 personDao 의 범위를 제한 합니다.
    val person: Person = getPerson()
    val personDao: PersonDao = getPersonDao()
    // 수행 결과를 반환 합니다.
    personDao.insert(person)
}
fun printAge(person: Person) = person.run {
    // person 을 수신객체로 변환하여 age 값을 사용합니다.
    print(age)
}

 

 

참고 사이트

GM.Lim 님의 블로그(개인적으로 설명이 잘되어있다고 생각한다.)

 

코틀린 의 apply, with, let, also, run 은 언제 사용하는가?

원문 : “Kotlin Scoping Functions apply vs. with, let, also, and run”

medium.com