본문 바로가기

Android 개인공부

코틀린 let, with, apply, also, run

반응형

Scope Functions

범위 지정 함수

- 수신 객체, 수신 객체 지정 람다 두가지 구성 요소를 가지는 함수.

 

수신 객체와 수신 객체 지정 람다는 어떤걸 의미할까?

ex)

Human("Kim", 30, "Seoul").let {
    println(it)
    it.moveTo("Busan")
    it.incrementAge()
    println(it)
}

위의 코드에서 Human 객체를 리시버, let 다음의 {  } 부분을 람다함수라고 한다.

해당 람다 함수에서 Human 객체에 접근할 수 있다.

 

해당 함수들을 이용하면 객체에 접근하는 방법을 쉽게 해주고 코드가 간결해지고 가독성이 높아지는 장점이 있다.

 

 

1. with()

inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    return receiver.block()
}

 

with() 함수 : 인자로 객체를 받고 블록에서 수행된 결과를 반환하는 함수

- Non-nullable 수신 객체 이고 결과가 필요하지 않은 경우에만 with 를 사용

 

ex)

val person: Person = getPerson()
with(person) {
    print(name)
    print(age)
}

 

2. also()

inline fun <T> T.also(block: (T) -> Unit): T {
    block(this)
    return this
}

 

also() 함수 : apply 함수와 마찬가지로 객체를 반환하며 let 과 동작이 매우 유사한 함수 하지만 let 에서는 내부 결과를 변화 시킬 수 있지만 also 에서는 변화 시킬 수 없다.

- 수신 객체 람다가 전달된 수신 객체를 전혀 사용 하지 않거나 수신 객체의 속성을 변경하지 않고 사용하는 경우 also 를 사용한다.

- also 는 apply 와 마찬가지로 수신 객체를 반환 하므로 블록 함수가 다른 값을 반환 해야하는 경우에는 also 를 사용할수 없다.

- 예를 들자면, 객체의 사이드 이팩트를 확인하거나 수신 객체의 프로퍼티에 데이터를 할당하기 전에 해당 데이터의 유효성을 검사 할 때 매우 유용

 

ex)

class Book(author: Person) {
    val author = author.also {
      requireNotNull(it.age)
      print(it.name)
    }
}


val numbers = mutableListOf("one", "two", "three")
numbers
    .also { println("The list elements before adding new one: $it") }
    .add("four")

 

3. apply()

inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

 

apply() 함수 : 블록에 자기 자신을 전달하고 이 객체를 반환하는 함수

- 수신 객체 람다 내부에서 수신 객체의 함수를 사용하지 않고 수신 객체 자신을 다시 반환 하려는 경우에 apply 를 사용하며 대표적인 경우가 객체의 초기화

 

ex)

val human = Human().apply {
    name = "Kim"
    age = 30
}

 

4. let()

inline fun <T, R> T.let(block: (T) -> R): R {
    return block(this)
}

 

let() 함수 : 블록에 자기 자신을 전달하고 수행된 결과를 반환하는 함수

- 지정된 값이 null 이 아닌 경우에 코드를 실행해야 하는 경우.

- Nullable 객체를 다른 Nullable 객체로 변환하는 경우.

- 단일 지역 변수의 범위를 제한 하는 경우.

 

ex)

var str="1"
val result=str?.let{// Int
    Integer.parseInt(it)
}
println(result)

 

5. run()

inline fun <T, R> T.run(block: T.() -> R): R {
    return block()
}

 

run() 함수 : 익명함수처럼 사용하거나, 블록에 자기 자신을 전달하고 수행된 결과를 반환하는 함수

- 어떤 값을 계산할 필요가 있거나 여러개의 지역 변수의 범위를 제한하려면 run 을 사용한다.

- 매개 변수로 전달된 명시적 수신객체 를 암시적 수신 객체로 변환 할때 run ()을 사용할수 있다.

 

ex)

val avg =run{
    val korean =100
    val english= 80
    val math=50
 
    (korean+english+math)/3.0
}
 
println(avg)

 

· 범위 지정 함수 의 호출시에 수신 객체가 매개 변수로 명시적으로 전달되거나 수신 객체의 확장 함수로 암시적 수신 객체 로 전달된다.

· 범위 지정 함수 의 수신 객체 지정 람다 에 전달되는 수신 객체가 명시적 매개 변수 로 전달 되거나 수신 객체의 확장 함수로 암시적 수신 객체로 코드 블록 내부로 전달 된다.

· 범위 지정 함수의 결과로 수신 객체를 그대로 반환하거나 수신 객체 지정 람다 의 실행 결과를 반환한다.

· 객체에 접근하는 방법은 this와 it(람다 인자)가 있다.

· run, with, apply는 this를 사용하여 객체에 접근하고 let과 also는 it를 사용한다.

· apply, also 는 리시버객체를 리턴한다.

· let, run, with 는 람다 함수의 마지막 결과를 리턴한다.

 

https://medium.com/@fatihcoskun/kotlin-scoping-functions-apply-vs-with-let-also-run-816e4efb75f5

 

 

참고자료 

beomseok95.tistory.com/95

 

Kotlin - 기타기능(let, with, apply, run 함수)

Kotlin - 기타기능(고차함수, 동반객체) 유용한 기타 기능 - 확장 함수 : 원래 있던 클래스에 기능을 추가하는 함수 - 형변환 : 숫자형 자료형끼리 쉽게 형변환 가능 - 형 체크 : 변수의 형이 무엇��

beomseok95.tistory.com

medium.com/@limgyumin/%EC%BD%94%ED%8B%80%EB%A6%B0-%EC%9D%98-apply-with-let-also-run-%EC%9D%80-%EC%96%B8%EC%A0%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80-4a517292df29

 

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

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

medium.com

codechacha.com/ko/kotlin-standard-library-functions/

반응형

'Android 개인공부' 카테고리의 다른 글

Android Custom Progress Dialog  (0) 2021.06.12
AAC LifeCycles  (0) 2020.12.16
Kotlin?  (0) 2020.11.26
FCM 푸쉬메시지 테스트 앱  (0) 2020.08.27
Gradle 동일 모듈 충돌시 해결  (0) 2020.08.20