변수 선언하기

코틀린에서 변수는 val, var 키워드로 선언한다. val은 value의 줄임말로 초깃값이 할당되면 바꿀 수 없는 변수를 선언할 때 사용한다. var은 variable의 줄임말로 초깃값이 할당된 후에도 값ㅇ르 바꿀 수 있는 변수를 선언할 때 사용한다.

val(//혹은 var) 변수명 : 타입 = 값

다음은 val과 var 키워드의 차이를 보여주는 예이다.

val data1 = 10
var data2 = 20

fun main(){
	data1 = 20 // 오류!
	data2 = 20 // 성공!
}

위 소스를 보면 data1과 data2 변수를 선언했다. 그런데 data1 변수는 val 키워드로 선언했으며 초깃값을 할당한 후 main() 함수에서 값을 변경하려고 시도한다. 여기서 컴파일 오류가 발생한다.

val키워드로 선언한 변수는 처음 할당한 값으로만 이용할 수 있다. 그런데 data2 변수는 var 키워드로 선언했으므로 값을 변경할 수 있다.

타입 지정과 타입 추론

변수명 뒤에는 콜론(:)을 추가해 타입을 명시할 수 있으며, 대입하는 ㄱ밧에 따라 타입을 유추(타입 추론)할 수 있을 때는 생략할 수 있다.

val data **: Int** = 10
val data2 = 10

위 소스에서 data1은 명시적으로 Int 타입을 선언한 것이며 data2는 대입한 값이 10이므로 타입을 명시하지 않아도 자동으로 Int 타입이 된다. 즉, val data2 : Int = 10 이라고 선언한 것과 똑같다.

초기값 할당

최상위에 선언한 변수나 클래스의 멤버 변수는 선언과 동시에 초기값을 할당해야 하며, 함수 내부에 선언한 변수는 선언과 동시에 초기값을 할당하지 않아도 된다.

물론 변수를 이용하려면 값을 할당하고 이용해야 한다.

val data1 : Int // 오류!
val data2 = 10 // 성공!

fun someFun(){
	val data3 : Int
	println("data3 : $data3") //오류!

	data3 = 10
	println("data3 : $data3") //성공!
}

class User{
	val data4 : Int       // 오류!
	val data5 : Int = 10  // 성공!
}

초기화 미루기

그런데 변수를 선언할 때 초깃값을 할당할 수 없는 경우가 있다. 이때는 값을 이후에 할당할 것이라고 컴파일러에게 알려 주어야 한다. 이때 lateinitlazy 키워드를 이용한다. lateinit 키워드는 이후에 초깃값을 할당할 것임을 명시적으로 선언한다.

lateinit var data1 : Int      // 오류!
lateinit val data2 : String   // 오류!
lateinit var data3 : String   // 성공!

lateinit로 선언한 변수는 선언과 동시에 초깃값을 할당하지 않아도 되지만 모든 유형의 변수 선언에 사용할 수는 없으며 다음 2가지 규칙을 따라야 한다.

  • lateinit은 var키워드로 선언한 변수에만 사용할 수 있다.
  • Int, Long, Short, Double, Float, Boolean, Byte 타입에는 사용할 수 없다.

lazy 키워드는 변수 선언문 뒤에 by lazy { } 형식으로 선언하며, 소스에서 변수가 최초로 이용되는 순간 중괄호로 묶은 부분이 자동으로 실행되어 그 결괏값이 변수의 초깃값으로 할당된다. lazy 문의 중괄호 부분을 여러 줄로 작성한다면 마지막 줄의 실행 결과가 변수의 초깃값이 된다

val data4 : Int by lazy {
	println("in lazy...")
	10
}

fun main(){
	println("in main.....")
	println(data4 + 10)
	println(data4 + 10)
}

결과

in main.....
in lazy.....
20
20