[Kotlin] 변수의 고급 기술 및 const, lateinit, lazy

박준규·2022년 1월 3일
0

코틀린

목록 보기
4/19

🤔 const

var과 val의 차이가 기억이 나는가? 아래의 코드를 보고 생각해보자.

var a = Coding("Kotlin", 2011)
a = Coding("Python", 1991)

var의 위와 같이 한 번 할당을 하더라도 새로운 객체로 변경하여 할당할 수 있다. 하지만 val은 그럴 수 없다는 것인데, 여기서 주의할 것이 필요하다.

val은 할당된 객체를 바꿀 수 없을 뿐이지 객체 내부 속성을 변경할 수 없는 것은 아니다.

근데 여기서 또 중요한 것은 절대 변경이 불가능한 것이 있다.

그것이 바로 상수const이다.

왜냐하면 상수는 컴파일 시점에 결정되어 절대 바꿀 수 없는 것이다.

코드는 다음과 같다.

const val CONST_CODING = "Kotlin"

상수로 표현할 수 있는 자료형은 기본 자료형(*String 포함)만 가능하다. 런타임에 생성될 수 있는 일반적인 다른 클래스의 객체들은 담수을 수 없다. 또한 상수는 클래스의 속성이나 지역 변수로는 다를 수 없다. 그리고 반드시 companion object 안에 선언해야 한다. 다음과 같이...

class Coding{
	companion object {
		const val CONST_CODING = "Kotlin"
	}
}

따라서 객체의 생성과 관계없이 클래스와 관련된 고정적인 값으로만 사용이 가능하다. 그리고 상수를 만들 때는 코드 스타일이 대문자 _ 만 사용하여 부분 짓게 된다. 이를 통해 변수가 아닌 상수라는 것을 알리게 된다. 근데 이건 대부분의 언어에서 이렇게 사용한다.

그러면 여기서 굳이 왜? const를 사용하는지 궁금하지 않은가? 왜냐하면 변수의 경우 runtime시 객체를 생성하는 데 더 많은 시간이 소요되기 때문이다. 즉 성능하락의 문제를 안고 있기 때문에 꼭 var를 써야하는 이유가 아니라면 const를 사용한다. 이를 통해 메모리에 값을 고정하여 사용함으로서 성능을 향상 시킬 수 있는 장점이 있다.

🤔 늦은 초기화(lateinit)

코틀린에서는 변수를 선언할 때 객체를 바로 할당하지 않는 경우가 많은데, 이 때 중요한 건 이러한 객체는 컴파일이 되지 않는다. 그래서 경우에 따라서 변수에 객체를 할당하는 것을 선언과 동시에 할 수 없는 경우도 많다. 이럴 때는 lateinit var a: String을 사용하여 일단 변수만 먼저 선언하고 초기값을 할당은 나중에 할수도 있다. 주의할 점은 다음과 같다.

lateinit var 변수의 제한 사항

  1. 초기값 할당 전까지 변수를 사용할 수 없음 (에러 발생)

  2. 기본 자료형에는 사용할 수 없음 (단, String class는 사용 가능)

  3. lateinit 변수에 초기화를 했는지에 대한 여부를 확인할 때는 변수 이름 앞에 콜론을 2번 붙이면 된다. 다음과 같이...

    ::a.isInitialized // 초기화 여부를 확인하는 것임

🤔 Lazy Delegate Properties (지연 대리자 속성)

Lazy는 lateinit과는 다르게 다음과 같이 사용한다.

val a:Int by lazy { 7 }

lazy라는 람다함수 형태의 초기화 함수를 사용하는 것과 같다.

코드에서는 선언시 즉시 객체를 생성 및 할당하여 변수를 초기화 하는 형태를 갖고 있다. 실제 실행시에는 val를 사용하는 시점에 초기화 과정을 진행함으로써 코드의 실행시간을 최적화 할 수 있는 코드입니다. 참고로 람다함수로 초기화가 진행되므로 함수안에 여러 개의 구문이 들어갈 수 있다. 마지막 구분의 결과가 할당되는 특성을 갖고 있다.

👔 예시 코드

fun main(args: Array<String>) {

    val codingBoot = CodingBoot()

    codingBoot.search(CodingBoot.SPARTA_CODING)
    codingBoot.search(CodingBoot.CODE_STATES)
    codingBoot.search(CodingBoot.RISING_CAMP)

    val a = LateInitSample()
    println(a.getLateInitText())
    a.text = "늦게 할당했쥐롱"
    println(a.getLateInitText())

    val number: Int by lazy {
        println("초기화 했지렁~")
        10
    }

    println("초기화를 시작합니당~")
    println(number)
    println(number)

}

class CodingBoot {
    fun search(bootName: String) {

        val price = when(bootName) {
            SPARTA_CODING -> "얼마인지 잘 모름..."
            CODE_STATES -> "뭐가 제일 쌈?"
            RISING_CAMP -> "근데 전 부트캠프 갈 생각은 없습니당.."
            else -> 0
        }

        println("${bootName}.. ${price}ㅎㅎ 가격은 진짜 모르겠습니다.")

    }

    companion object {
        const val SPARTA_CODING = "스파르타코딩"
        const val CODE_STATES = "코드스테이트"
        const val RISING_CAMP = "라이징캠프"
    }
}

class LateInitSample{
    lateinit var text:String

    fun getLateInitText(): String {
        if(::text.isInitialized) {
            return "text"
        } else {
            return "default"
        }
    }
}
profile
'개발'은 '예술'이고 '서비스'는 '작품'이다

0개의 댓글