Menu
Coddy logo textTech

lazy와 lateinit

Coddy Kotlin 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 10번째.

by lazy { ... }는 val의 계산을 처음 읽을 때까지 지연한 다음, 그 결과를 기억합니다. 비용이 많이 들거나 항상 필요하지는 않은 값에 적합합니다:

class Report(val rows: List<Int>) {
    val summary: String by lazy {
        println("computing summary")
        "total ${rows.sum()}"
    }
}

main 내부에서:

val r = Report(listOf(3, 4))
println("created")
println(r.summary)
println(r.summary)

출력:

created
computing summary
total 7
total 7

블록은 한 번 실행됩니다. 위의 두 번째 읽기에서는 저장된 결과를 사용했습니다. 매번 읽을 때마다 실행되는 사용자 지정 getter와 달리, lazy는 한 번 계산하고 캐시합니다:

class Demo {
    var reads = 0
    val viaGetter: Int
        get() { reads++; return 42 }
    val viaLazy: Int by lazy { reads++; 42 }
}

main 내부:

val d = Demo()
repeat(3) { d.viaGetter; d.viaLazy }
println(d.reads)

출력:

4

lateinit var는 생성 이후, 예를 들어 설정 메서드에 의해 나중에 할당되는 null이 아닌 프로퍼티를 선언합니다. 할당되기 전에 읽으면 예외가 발생하며, ::name.isInitialized로 초기화 여부를 확인합니다:

class Screen {
    lateinit var title: String

    fun load(t: String) { title = t }
    fun ready() = ::title.isInitialized
}

main 내부에서:

val s = Screen()
println(s.ready())
s.load("Home")
println(s.ready())
println(s.title)

출력:

false
true
Home

생성 시점에 값이 이미 정해져 있다면 일반 초기화를 우선 사용하세요. 필요하지 않을 수도 있는 비용이 큰 val에는 lazy를 사용하고, 값이 실제로 나중에 할당되는 var에만 lateinit을 사용하세요. lateinit은 Int, Boolean 또는 기타 원시 타입과 함께 사용할 수 없습니다.

val config by lazy { loadConfig() }     // 처음 사용할 때 한 번 계산됨
lateinit var user: User                 // 생성 후 할당됨
// lateinit var count: Int              // 오류: 원시 타입에는 허용되지 않음
challenge icon

챌린지

쉬움

Document(val text: String) 클래스를 완성하세요. 단일 공백으로 구분된 단어 수를 세고 각 계산마다 computations에 1을 더해 기록하는 lazy 프로퍼티 wordCount를 추가하고, 저자가 설정되지 않았을 때 by Ada 또는 by unknown을 반환하는 메서드 credit()과 lateinit var author: String을 추가하세요.

제공된 코드는 텍스트를 읽고, wordCount를 세 번 읽고, 두 번째 줄이 있으면 저자를 설정한 다음 words 5, computed 1, by Ada를 출력합니다.

코드는 Document.kt에 작성하세요. Main.kt에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.

직접 해보기

fun main() {
    // 제공된 입력/출력 코드: 그대로 유지하세요
    val input = generateSequence(::readLine).toList()
    val doc = Document(input[0])
    val reads = List(3) { doc.wordCount }
    val words = reads.first()
    if (input.size > 1) doc.author = input[1]
    println("words $words, computed ${doc.computations}, ${doc.credit()}")
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: Kotlin 플레이그라운드