본문 바로가기
Android/Kotlin

Scope Function

by KDGdev 2023. 2. 21.

Scope 함수


Scope 함수란 객체를 할당하고 배정할 수 있는 공간인 Object context 내에서 코드 블록을 실행하기 위한 목적만을 가진 함수입니다.

 

Scope 함수들을 람다식으로 호출할 때, 이는 임시로 범위(scope)를 형성합니다. 이 범위 내에서는 객체의 이름이 없어도 객체에 접근할 수 있습니다.

 

이러한 용도로 코드들을 더욱 간결하고 가독성을 좋게 합니다.

 

let

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

// <T, R> -> 타입 파라미터
// (T) -> 리시버 -> it
// : R -> 리턴 타입 - 블럭에 마지막 코드

val length = str?.let {
    it.length
} ?: 0

 

타입 파라미터 <T, R>이란 Scope함수를 사용할 타입인 T와 리턴값인 R을 의미합니다.

 

T.let에서 알 수 있다 시피 let 함수는 str?. let처럼 사용할 변수 뒤에 붙습니다.

또한 block: (T)에서 T를 인자로 받고 있기 때문에 코드 블록 내에서 it을 사용합니다.

 

마지막으로 코드블록 내의 결괏값, 즉 코드블록의 마지막 코드를 반환합니다.

 

위의 예제와 같이 객체의 값이 null이 아닐 때 let을 실행시키고 null일 때에 엘비스 연산자인?:을 통해 null 값을 처리하는 용도로 사용됩니다.

 

run

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

val service = MultiportService("<https://example.kotlinlang.org>", 80)

val result = service.run {
    port = 8080
    query(prepareRequest() + " to port $port")
}

 

let과 마찬가지로 사용할 변수 뒤에 붙습니다.

 

하지만 block: T.()이기 때문에 this를 사용하고 생략이 가능합니다.

 

결괏값은 let과 같이 코드블록 내의 결괏값을 반환합니다.

 

run은 객체의 초기화, 객체 내의 어떤 값이나 특정한 값이 필요할 때 사용됩니다.

 

 

with

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

val numbers = mutableListOf("one", "two", "three")
with(numbers) {
    println("'with' is called with argument $this")
    println("It contains $size elements")
}

 

다른 scope 함수와 달리 T.with이 아닌 with이고 receiver: T가 있기 때문에 with(T)으로 사용합니다.

 

T.()과 R이기 때문에 run처럼 this를 사용하고 run과 let처럼 코드블럭내의 결과값을 반환합니다.

 

객체의 함수를 여러 개 호출할 때 그룹화하는 용도로 사용합니다.

 

apply

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

val adam = Person("Adam").apply {
    age = 32
    city = "London"
}

 

앞의 예제들과 달리 R이 Unit으로 바뀌었습니다. 이는 결괏값으로 해당 객체를 반환한다는 뜻입니다. return this 보이시죠?

 

또한 T.()이기 때문에 this를 사용합니다.

 

객체의 생성과 초기화에 주로 사용됩니다.

 

also

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

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

apply와 마찬가지로 객체를 반환합니다. 또한 (T)이기 때문에 it을 사용합니다.

 

로깅이나 디버그 정보를 출력하는 것과 같이 객체를 변화시키지 않는 부가적인 작업을 하는 용도로 사용합니다.

 

마무리

총정리를 해보자면

  it this
객체 also apply
코드블럭 let run, with

 

사용하는 용도가 명확히 정해져 있는 건 아니니 편한 대로 사용하면 됩니다.

 

this는 생략할 수 있어 깔끔한 코드를 만들 수 있고 it은 원하는 대로 명칭을 바꿀 수 있어 가독성을 좋게 할 수 있습니다.

 

또한 객체를 반환하는 것은 객체의 초기화와 인스턴스 생성을 동시에 할 때 좋고 코드블럭은 특정 값이 필요할 때 좋습니다.

 

※ 잘못된 정보, 혹은 다른 의견이 있다면 댓글로 말해주세요. 감사합니다.

 

'Android > Kotlin' 카테고리의 다른 글

백킹프로퍼티(Backing Properties)란?  (0) 2023.04.06
Kotlin 연산자 - ? / !! / ?: / is / as  (0) 2023.02.22
List, Set, Map  (0) 2023.02.20