Search

Type Check and Cast

런타임에 객체의 타입을 확인하기 위해 검사를 수행할 수 있다.
타입 캐스트를 사용하면 객체를 다른 타입으로 변환할 수 있다.

is 및 !is 연산자

is!is 를 통해 객체가 주어진 타입인지 여부를 식별하는 런타임 검사를 수행한다.
if (obj is String) { print(obj.length) } if (obj !is String) { // Same as !(obj is String) print("Not a String") } else { print(obj.length) }
Kotlin
복사

스마트 캐스트

대부분 컴파일러가 자동으로 객체를 캐스트하기 때문에 명시적 캐스트 연산자를 사용할 필요가 없다.
컴파일러는 불변 값에 대한 타입 검사와 명시적 캐스트를 추적하고 필요한 경우 암묵적 캐스트를 삽입한다.
fun demo(x: Any) { if (x is String) { print(x.length) // x is automatically cast to String } } fun demo(x: Any) { if (x !is String) return print(x.length) // x is automatically cast to String }
Kotlin
복사
제어 흐름
스마트 캐스트는 if 조건식뿐만 아니라 when 표현식과 while 루프에도 적용된다.
when (x) { is Int -> print(x + 1) is String -> print(x.length + 1) is IntArray -> print(x.sum()) }
Kotlin
복사
스마트 캐스트를 이용해 boolean 조건을 변수로 추출하여 사용할 수 있다.
class Cat { fun purr() { println("Purr purr") } } fun petAnimal(animal: Any) { val isCat = animal is Cat if (isCat) { // The compiler can access information about // isCat, so it knows that animal was smart-cast // to the type Cat. // Therefore, the purr() function can be called. animal.purr() } } fun main(){ val kitty = Cat() petAnimal(kitty) // Purr purr }
Kotlin
복사
논리 연산자
컴파일러는 && 또는 || 연산자 왼쪽에 타입 체크가 있는 경우 오른쪽에서 스마트 캐스트를 수행한다.
// x is automatically cast to String on the right-hand side of `||` if (x !is String || x.length == 0) return // x is automatically cast to String on the right-hand side of `&&` if (x is String && x.length > 0) { print(x.length) // x is automatically cast to String }
Kotlin
복사
인라인 함수
외부 스코프에 있는 변수를 인라인 함수에 전달하여 사용할 때 스마트 캐스트를 수행한다.
interface Processor { fun process() } inline fun inlineAction(f: () -> Unit) = f() fun nextProcessor(): Processor? = null fun runProcessor(): Processor? { var processor: Processor? = null inlineAction { // The compiler knows that processor is a local variable and inlineAction() // is an inline function, so references to processor can't be leaked. // Therefore, it's safe to smart-cast processor. // If processor isn't null, processor is smart-cast if (processor != null) { // The compiler knows that processor isn't null, so no safe call // is needed processor.process() } processor = nextProcessor() } return processor }
Kotlin
복사
예외 처리
스마트 캐스트 정보는 catch 및 finally 블록으로도 전달됩니다.
fun testString() { var stringInput: String? = null // stringInput is smart-cast to String type stringInput = "" try { // The compiler knows that stringInput isn't null println(stringInput.length) // 0 // The compiler rejects previous smart cast information for // stringInput. Now stringInput has the String? type. stringInput = null // Trigger an exception if (2 > 1) throw Exception() stringInput = "" } catch (exception: Exception) { // The compiler knows stringInput can be null // so stringInput stays nullable. println(stringInput?.length) // null } }
Kotlin
복사
스마트 캐스트 전제조건
스마트 캐스트는 컴파일러가 변수의 검사와 사용 사이에 변경이 없다고 보장할 때만 작동한다.
1.
val 지역 변수
a.
항상 (로컬 위임된 프로퍼티 제외)
2.
val 프로퍼티
a.
private, internal 이 선언된 동일한 모듈에서 검사가 수행되는 경우 작동
b.
open 이 선언되었거나 커스텀 게터가 있는 경우 작동하지 않음
3.
var 지역 변수
a.
변수의 값이 검사와 사용 사이에 변경되지 않아야 작동
b.
변수가 값을 변경하는 람다에 캡쳐되지 않아야 작동
c.
변수가 로컬 위임된 프로퍼티가 아니어야 작동
4.
var 프로퍼티
a.
언제든지 다른 코드에 의해 수정될 수 있기 때문에 절대 작동하지 않음

캐스트 연산자

as
객체를 null이 불가능한 타입으로 명시적으로 캐스팅하기 위한 연산자
해당 연산자를 사용하여 nullable한 타입으로 캐스팅하려면 오른쪽에 nullable한 타입을 사용
캐스트가 불가능한 경우 예외 발생
val x: String = y as String
Kotlin
복사
as?
캐스팅 시 예외를 방지하기 위해 사용하는 연산자
nullable 타입이 아닌 경우에도 캐스팅 결과는 null을 허용
val x: String? = y as? String
Kotlin
복사