Coding Memo

Kotlin 스코프 함수 본문

Language/Kotlin

Kotlin 스코프 함수

minttea25 2021. 1. 2. 15:34

스코프 함수 (Scope Function)

 

Kotlin 기본 라이브러리에서 제공하는 기본 함수로 객체를 직접 생성하지 않고 그 객체의 함수를 사용할 수 있다.

 

Kotlin의 스코프 함수는 5가지가 있다.

apply

run

with

also

let

 

각 함수들은 역할이 비슷하다.


apply

 

apply는 자기 자신을 반환한다.

this. 와 같은 참조 연산자를 따로 사용할 필요가 없다. (하지만 같은 이름의 변수가 있을 수 있으니 붙여서 사용하자)

보통 body 부분에서 값을 초기화하기 위해 사용하며 property(속성)만을 사용한다. (함수 사용 x)

class Book (title: String, price: Int) {
    var title: String = title
    var price: Int = price

    var code: String = ""

    fun printInfo() {
        println("title: $title, price: $price, code: $code")
    }
}

fun main() {
    var b = Book("Harry Potter", 10000)
        .apply {
        title = "Harry Potter and the Chamber of Secrets"
        code = "A1B2C3"
        }.printInfo()
}

 

apply 예시 출력 결과

 

b 객체의 값을 변경할 때 this와 같은 키워드나 참조 연산자를 따로 사용하지 않고 값을 변경했다.

apply 옆에 'this: Book'이 표시되어 있다.


run

 

apply와 비슷하지만 차이점은 return 값이 this가 아니라 구문이 있는 블록의 return 값이다.

run 블록의 마지막 구문에서 return이 된다.

 

class Book (title: String, price: Int) {
    var title: String = title
    var price: Int = price

    var type: String = ""
    var code: String = ""

    fun printInfo() {
        println("title: $title, price: $price, code: $code")
    }
}

fun main() {

    var b = Book("Harry Potter", 10000).apply { type = "Novel" }
    if (b.run { (this.type == "Novel") }) {
        println("b is novel")
    }
}

run 예시 출력 결과

'b.run { (this.type == "Novel") }'의 결과값이 true 이므로 println()이 실행되었다.


with

 

run과 하는 일은 같고, 인스턴스를 파라미터로 받는다는 점만 다르다.

즉 b.run{} 과 with(a){}는 같다.

class Book (title: String, price: Int) {
    var title: String = title
    var price: Int = price

    var type: String = ""

    fun printInfo() {
        println("title: $title, price: $price, type: $type")
    }
}

fun main() {

    var b = Book("Harry Potter", 10000).apply { type = "Novel" }

    var isNovel1: Boolean = with(b) {
        type == "Novel"
    }

    //same as with(b){}
    var isNovel2 = b.run { type == "Novel" }

    println("isNovel1 = $isNovel1")
    println("isNovel2 = $isNovel2")
}

with 예시 출력 결과


also

 

간단하게 말하면, apply랑 하는 일은 같지만 파라미터를 인스턴스를 파라미터로 받고 그것을 'it'으로 사용한다.

 

class Book (title: String, price: Int) {
    var title: String = title
    var price: Int = price

    var type: String = ""

    fun printInfo() {
        println("title: $title, price: $price, type: $type")
    }
}

fun main() {
    var b = Book("Harry Potter", 10000)
        .also { it.printInfo() }
}

also 예시 출력 결과


let

 

run과 같은 역할을 하고 also와 마찬가지로 파라미터로 인스턴스 자신을 받고, 그것을 'it'으로 사용한다.

(run과 같은 역할을 하지만 같은 이름의 변수의 혼란을 방지하기 위해서 사용하기도 한다.)

 

null 이 아닌 값을 가지는 코드 블록을 실행시킬 때도 let이 쓰인다.

class Book (title: String, price: Int) {
    var title: String = title
    var price: Int = price

    var type: String = ""

    fun printInfo() {
        println("title: $title, price: $price, type: $type")
    }
}

fun main() {

    var b = Book("Harry Potter", 10000).apply { type = "Novel" }

    var isNovel1: Boolean = with(b) {
        type == "Novel"
    }

    //same as with(b){}
    var isNovel2 = b.run { type == "Novel" }

    var isNovel3 = b.let { it.type == "Novel" }

    println("isNovel1 = $isNovel1")
    println("isNovel2 = $isNovel2")
    println("isNovel3 = $isNovel3")
}

let 예시 출력 결과


간단한 특징만 정리한 표는 다음과 같다.

  apply run with also let
Context Object this it
return self(this) block() self(this) block()

return 값

apply, also: 자기 자신 (컨텍스트 객체)

run, with, let: 블록 구문의 반환 값 (람다식의 반환 값)

 

인터넷에 검색해보면 정말 정말 잘 정리해놓은 글들이 많다.

 

위의 예시들은 굉장히 간단한 예시이고 좀 더 알고 싶으면 다음의 공식 문서를 확인해보는 것이 좋다.

https://kotlinlang.org/docs/reference/scope-functions.html

 

Scope Functions - Kotlin Programming Language

 

kotlinlang.org

 

스코프 함수는 이것저것 찾아보면서 써 내려갔지만 개념 자체는 쉬워 보여도 활용하기가 어려운 부분처럼 보인다...

 

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

Kotlin 옵저버 패턴  (0) 2021.01.03
Kotlin 오브젝트  (0) 2021.01.03
Kotlin 인터페이스  (0) 2021.01.02
Kotlin 고차 함수 / 람다 함수  (0) 2020.12.31
Kotlin 클래스  (0) 2020.12.30