Kotlin 의 nullable type 추론 이슈 해결

in #kr-dev7 years ago (edited)

다음과 같은 코드를 생각해보자.

fun execIntFunctContainer( funcContainer: FuncContainer<Int> ) {  
funcContainer.func(123) 
}

class FuncContainer<T>(val func: (input: T?) -> Unit)

val a = FuncContainer({ a: Int? -> print(a)})

execIntFunctContainer( a)

T 라는 타입 매개변수를 갖는 FuncContainer 클래스는 T? 타입의 입력을 받아 아무것도 반환하지 않는 함수를 func라는 속성으로 가진다.

execIntFuncConstainer는 Int를 타입매개변수로 갖는 FuncContainer 인스턴스를 인자로 받아, 이 인자의 func 를 실행한다.

마지막으로 a 라는 필드에 FuncContainer의 인스턴스를 만들어, execIntFuncContainer 에 인자로 넘겨 함수를 호출한다. a 를 만들 때 명시적인 타입 매개변수를 정의하진 않았지만 대충 Int라고 추론하지 않을까 기대를 했다.

하지만 실행하면 아래와 같은 에러가 난다.

error: type mismatch: inferred type is Line_13.FuncContainer<Int?> but Line_13.FuncContainer<Int> was expected

execIntFunctContainer 에는 FuncContainer<Int> 타입의 인자를 넘겨야 하는데 왜 FuncContainer<Int?> 타입의 인자를 넘겼냐고 한다. 즉, 코틀린은 a 의 타입 매개변수를 추론할 때 Int 라고 생각하지 않고 Int? 이라고 생각했나보다.

이 문제를 해결하는 별로 아름답지 않는 방법은 그냥 a 를 선언할 때 명시적으로 타입 매개변수를 주면 된다.

val a = FuncContainer<Int>({ a: Int? -> print(a)})

하지만 별로 마음에 들지 않는다. 이 때엔 만약 FuncContainer의 타입 매개변수로 nullable type을 허용하지 않는다면, 다음과 같이 non-nullable type인 Any만 받겠다고 타입 매개변수에 제약을 가하면 된다.

class FuncContainer<T: Any>(val func: (input: T?) -> Unit)
Sort:  

Resteemed your article. This article was resteemed because you are part of the New Steemians project. You can learn more about it here: https://steemit.com/introduceyourself/@gaman/new-steemians-project-launch