lateinit, lazy

하승진·2024년 7월 29일
0
post-thumbnail

Intro

var은 한 번 할당한 객체가 있더라도 다른 객체로 할당 가능하며
val은 한 번 객체를 할당하면 다시 할당된 객체를 변경 못한다.
하지만 val은 다시 할당을 못할 뿐이지 속성은 변경 가능하다.

상수는 할당도 속성도 변경 못한다.

상수

const val CONST_A = 1234

이런 형태로 val 앞에 반드시 const를 붙이고, 대문자와 언더바(_)로 변수 이름을 만들어줘야 한다.

  • 상수로 선언될 수 있는 값은 기본 자료형만 가능
  • 런타임에 생성될 수 있는 일반적인 다른 클래스의 객체들은 불가능

따라서

class Sample {
	const val CONST_A = 1234
}

fun sample {
	const val CONST_A = 1234
}

이렇게 클래스와 함수 내에 상수 선언은 불가능하다.
그래서 반드시

class Sample {
	companion object {
    	const val CONST_A = 1234
    }
}

companion object 안에 선언하여 객체의 생성과 관계없이 클래스와 관계된 고정적인 값으로만 사용하게 된다.

예제를 보면 companion object 안에 선언한 상수들은 searchPrice함수의 파라미터로 활용하여 각 상황에 맞도록 when으로 그에 맞는 값을 반환하도록 했다.

상수 사용하는 이유?

: 이는 변수의 경우 런타임시 객체를 생성하는데 시간이 더 소요되어 성능의 하락이 있기 때문
: 늘 고정적으로 사용할 값은 상수를 통해 객체의 생성없이 메모리에 값을 고정하여 사용함으로서 성능을 향상시킬 수 있다는 장점

lateinit

코틀린에서는 변수를 선언할 때 바로 할당하지 않는 경우 컴파일에 에러가 발생
하지만 상황에 따라서 변수에 객체를 할당하는 것을 선언과 동시에 할 수 없을 때도 있다.

lateinit var a: Int

이럴 때 이러한 형식처럼 var 앞에 lateinit이라는 키워드를 명시해주면 된다.
일단 변수만 선언하고, 초기값의 할당은 나중에 할 수 있도록 하는 키워드이다.

제한 사항

  • 초기값 할당 전까지 변수를 사용 불가능
  • 기본 자료형에는 사용 불가능 (String 클래스에는 사용 가능)

isInitialized

: lateinit 변수의 초기화에 대한 여부를 확인 시

::a.isInitialized

라는 형태로 작성하여 초기화가 되었는지 확인하여 사용할 수 있기에 오류 방지 가능

이렇게 할당하기 전에는 else 문으로 기본값 이라는 문자열이 반환되고, 할당한 이후에는 할당값이 반환이 된다.

lazy(지연 대리자 속성)

: 변수를 사용하는 시점까지 초기화를 자동으로 늦춰주는 속성

val a: Int by lazy {7}
...
println(a)

이와같이 자료형 옆에 "by" 키워드를 사용하여 lazy라는 람다 함수형태의 초기화 함수를 사용하는 형태로 코드에서는 선언 시 즉시 객체를 생성 및 할당하여 변수를 초기화하는 형태를 갖고 있지만 실제 실행시에는 println하는 시점에 7로 초기화 된다.
이는 코드의 실행시간을 최적화 할 수 있는 장점이다.
람다 함수로 초기화가 진행되므로

val a: Int by lazy {
	println("initializing")
    7
}

이와 같이 여러 개의 구문이 들어갈 수 있으며 맨 마지막의 결과가 변수에 할당된다.

이와같이 코드를 시작한 뒤 number 처음 출력할 때 lazy함수를 통해 초기화가 진행되었음을 알 수 있으며 두 번째 number 출력 시 이미 초기화를 했기 때문에 다시 초기화 구문을 실행하지 않는다.

profile
기어갈지언정 한 발자국씩이라도 가보자

0개의 댓글