[Kotlin]Context Object

Hood·2024년 8월 27일

Kotlin

목록 보기
4/18
post-thumbnail

✍ 코틀린과 친해지자

PS 문제를 하나씩 풀다 보니, 공부가 필요하다고 느낀 문법에 대해 정리한 글입니다.


🔎 컨텍스트 객체 : this or it

스코프 함수를 정리하다 보면 Context 객체와 관련된 this, it 키워드가 등장합니다.
이번에는 컨텍스트 객체에 대해 정리해보려고 합니다.

공식 문서에 따르면, 컨텍스트 객체는
새롭게 형성된 람다 내부에서 현재 작업의 기준이 되는 객체라고 볼 수 있습니다.

범위 함수에 전달된 람다 내부에서는 컨텍스트 객체를 실제 이름 대신 짧은 참조로 사용할 수 있습니다.
각 스코프 함수는 컨텍스트 객체를 참조하는 두 가지 방식 중 하나를 사용합니다.


this

run, with, apply는 컨텍스트 객체를 lambda receiver로 참조하며, 이때 this 키워드를 사용합니다.
대부분의 경우 수신 객체의 멤버에 접근할 때 this를 생략할 수 있기 때문에, 코드를 더 짧게 작성할 수 있습니다.

class ThisPerson(var name: String, var age: Int? = null)

fun main() {
    val person = ThisPerson("smith", 28)
    person.run {
        println("이름 : ${this.name}")
        println("나이 : ${this.age}")
    }

    val park = ThisPerson("Park").apply {
        age = 28
    }

    park.run {
        println("이름 : $name")
        println("나이 : $age")
    }
}

위 예제를 보면 ThisPerson이라는 클래스를 만들고, "smith"28이라는 값을 넣어 객체를 생성하였습니다.
처음에는 run 스코프 함수를 통해 이름과 나이를 출력하고 있는데, 이때 객체를 다시 클래스 이름으로 접근하는 것이 아니라 this를 통해 참조하고 있습니다.

즉, this는 현재 스코프에서 기준이 되는 객체 자신을 가리킬 때 사용됩니다.

대부분의 경우 수신 객체의 멤버에 접근할 때 this를 생략할 수 있으므로 코드가 더 짧아집니다.
반면 this를 생략하면 수신 객체의 멤버와 외부 객체 또는 함수를 구분하기 어려워질 수도 있습니다.

따라서 컨텍스트 객체를 수신자(this)로 사용하는 방식은 다음과 같은 경우에 주로 권장됩니다.

  • 객체의 함수를 호출할 때
  • 객체의 속성에 값을 할당할 때
  • 객체의 멤버를 중심으로 동작하는 람다를 작성할 때

it

itlet, also처럼 람다의 인자 이름을 따로 지정하지 않았을 때 사용되는 기본 이름입니다.
따라서 this보다 짧게 사용할 수 있고, 표현식도 비교적 읽기 쉬워지는 경우가 많습니다.

다만 it은 객체를 인자로 받는 형태이기 때문에, this처럼 객체의 함수나 속성에 암묵적으로 접근할 수는 없습니다.
그래서 다음과 같은 경우에 자주 사용됩니다.

  • 객체가 함수 호출의 인수로 주로 사용되는 경우
  • 컨텍스트 객체를 명시적으로 전달하면서 사용할 때
  • 코드 블록 안에서 여러 변수를 함께 다루는 경우
import kotlin.random.Random

fun writeToLog(message: String) {
    println("INFO: $message")
}

fun main() {
    fun getRandomInt(): Int {
        return Random.nextInt(100).also {
            writeToLog("getRandomInt()에 생성된 값 $it")
        }
    }

    val i = getRandomInt()
    println(i)
}

위 예제처럼 스코프 함수 안에서 인수 이름을 따로 지정하지 않으면,
람다 내부에서 암묵적으로 it이라는 이름이 사용되는 것을 확인할 수 있습니다.

import kotlin.random.Random

fun writeToLog(message: String) {
    println("INFO: $message")
}

fun main() {
    fun getRandomInt(): Int {
        return Random.nextInt(100).also { value ->
            writeToLog("getRandomInt()에 생성된 값 $value")
        }
    }

    val i = getRandomInt()
    println(i)
}

또한 위와 같이 인수 이름을 value로 직접 지정하면,
it보다 의미가 더 분명해져서 코드의 의도를 더 쉽게 파악할 수 있습니다.


📌 결론

오늘은 Kotlin 스코프 함수에서 사용하는 Context Object에 대해 알아보았습니다.
thisit의 차이를 잘 이해하고 상황에 맞게 사용하면, 코드를 더 간결하고 읽기 쉽게 작성할 수 있습니다.

참고

profile
달을 향해 쏴라, 빗나가도 별이 될 테니 👊

0개의 댓글