코틀린의 프로퍼티, 스마트 캐스트(타입 검사, 타입 캐스트, 타입 강제 변환)에 대해 알아보겠습니다. 이 문서는 Kotlin In Action을 참고하여 공부하고 정리한 내용입니다. 그럼 오늘도 화이팅 입니다. 🌿
식과 문
식 : 식은 값을 만들어 내며, 다른 식의 하위 요소로 계산에 참여할 수 있다.
문 : 문은 자신을 둘러싸고 있는 가장 안쪽 블록의 최상위 요소로, 아무런 값을 만들어내지 않는다.
코틀린의 함수는 표현 방식에 따라, 식이 본문인 함수와 블록이 본문인 함수로 분류됩니다.
식이 본문인 함수
fun max(a: Int, b:Int) : Int = if (a>b) a else b
식이 본문인 함수는 반환 타입을 생략할 수 있습니다.
fun max(a: Int, b:Int) = if (a>b) a else b
정적 타입 지정 언어인 코틀린인데, 반환 타입을 생략해도 되나요 ?
정적 타입 지정 언어라는 것은 "컴파일 시점에 모든 변수나 모든 식의 타입, 모든 함수는 반환 타입이 정해져야 한다."라는 의미를 가집니다. 따라서 반환 타입을 적지 않는 식이 본문인 함수 표현 방식에 의문을 가질 수 있습니다.
식이 본문인 함수를 보면 =를 기준으로 오른쪽은 값을 만들어내는 식 입니다. 따라서 컴파일러는 컴파일 시점에 식의 결과 타입을 알 수 있으며, 이 결과 타입을 함수의 반환타입으로 지정해줄 수 있는 것 입니다. 이렇게 컴파일러가 타입을 분석해 프로그래머 대신 프로그램 구성 요소의 타입을 정해주는 기능을 타입 추론이라고 합니다.
타입 추론은 이 뿐 아니라, 변수 초기화 시에 타입 지정을 생략할 수 있는 이유가 되기도 합니다.
val answer = 2 * 10
value(값)인 val
변경 불가능한 참조를 저장하는 변수다.
자바의 final에 해당됩니다.
val의 활용
딱 한번만 초기화하기
값을 딱 한 번만 초기화해야하므로, 분기처리 활용에 좋습니다.
어느 분기로 가든, 딱 한번만 초기화 된다는 것은 컴파일러가 보장하는 로직이 될 것입니다.
val msg: String
if (canPerform()) {
msg = "200"
}
else {
msg = "400"
}
객체를 참조하고, 객체의 값을 바꾸기 (ex. arrayListOf)
val은 변경 불가능한 참조를 저장하는 변수라고 했습니다. 즉, 참조 자체는 불변일지라도, 해당 참조가 가리키는 객체의 내부 값은 변경될 수 있다는 의미이기도 합니다.
아래 대입문을 분석해보면, 두개의 객체를 찾을 수 있습니다. arrayListOf("Kotlin1")로 선언된 객체(이하 obj)와 obj를 가리키는 객체 mList가 그 두 객체입니다.
앞서 설명한 내용을 조합해보면, "변경 불가능한 참조를 저장하는 변수"라는 것은 mList 값인, obj에 대한 참조(mList가 obj를 가리키는 것)가 변경 불가능 하다는 것이며, obj의 값 변경 여부에 대한 제약은 없다는 것을 알 수 있습니다.
따라서, mList(obj에 대한 참조)를 통해 obj의 값을 변경시키는 것은 정상적인 활용이 되는 것입니다.
val mList = arrayListOf("Kotlin1")
mList.add("Kotlin2")
variable(변할 수 있는)인 var
변경 가능한 참조를 저장하는 변수다.
자바의 일반 변수에 해당됩니다.
var의 주의 사항
변수의 값은 변경 가능, 변수의 타입은 변경 불가능 !
컴파일러가 기대하는 타입은 변수 서언 시점의 초기화 식으로부터 추론한 변수의 타입입니다.
따라서, var 변수의 재대입이 이뤄질 때는 이미 추론한 변수의 타입을 기대하고, 대입문의 타입을 검사합니다.
val answer = 2 * 10
answer= "20" // "Error: tyoe mismatch"