코틀린은 2010년에 처음 개발되었지만 2016년 2월에 첫 번째 안정 버전(stable version)이 공식적으로 배포되었을 정도로 굉장히 오랜 시간 동안 만들어지고 있고, 처음부터 대규모 애플리케이션을 실용적으로 만들기 위한 프로그래밍 언어로 설계되었고 현재는 모바일 애플리케이션, 웹 애플리케이션의 백엔드, 웹 애플리케이션의 프론트엔드 등 다양한 영역에서 활용되고 있습니다.
4️⃣ Inferred 타입 제한
코틀린의 타입 추론(type inference)은 코틀린의 특징 중 하나이지만 타입 추론을 사용할 때는 몇 가지 위험한 부분들이 있기 때문에 잘 못 사용해선 안됩니다.
이러한 위험을 피하기 위해선 할당 시 inferred 타입은 절대로 슈퍼클래스 또는 인터페이스로 설정되지 않고 할당하려는 값에 맞게 설정됩니다.
아래 예제를 확인해보면 위에서 말했듯이 inferred 타입인 food는 Steak 타입으로 타입 추론이 되었기 때문에 슈퍼클래스인 Food 타입을 할당할 수 없습니다.
open class Food
class Steak: Food()
fun main() {
var food = Steak() // Type : Steak
food = Food() // 오류 : 타입의 불일치
}
만약 원하는 Food 타입 보다 제한된 Steak 타입이 설정되어있으니 타입 불일치가 발생하는 것은 당연합니다. 이를 Food 타입을 명시적으로 지정해주면 간단히 해결됩니다.
open class Food
class Steak: Food()
fun main() {
var food: Food = Steak() // Type : Food
food = Food() // Type : Food
}
그리고 inferred 타입을 노출하면, 잠재적으로 오류를 불러올 수 있습니다. inferred 타입의 노출에 위험성에 대한 간단한 예를 들어보겠습니다.
val DEFAULT_FOOD : Food = DEFAULT()
interface Kitchen {
fun cook() : Food = DEFAULT_FOOD
}
.. 생략 ..
위 예제를 확인해보면 기본으로 생성되는 식품을 DEFAULT를 반환하도록 했는데, DEFAULT_FOOD는 Food 타입으로 명시되어 있으니 필요없다고 생각되어 아래처럼 수정했다고 생각해봅시다.
val DEFAULT_FOOD : Food = DEFAULT()
interface Kitchen {
fun cook() = DEFAULT_FOOD // <-- 수정된 부분
}
open class Food: Kitchen {
override fun cook() = this
}
class DEFAULT : Food()
class Pasta : Food()
fun main() {
val defaultFood1 = Pasta().cook()
val defaultFood2 = DEFAULT().cook()
println(defaultFood1)
println(defaultFood2)
}
이후에 다른 사람이 코드를 보다가, DEFAULT_FOOD는 타입 추론에 의해 자동으로 타입이 지정될 것이라고 생각하고 아래와 같이 수정하게되면 Kitchen 인터페이스는 DEFAULT 이외의 식품을 만들 수 없고 오류가 발생합니다.
val DEFAULT_FOOD = DEFAULT() // <-- 수정된 부분
interface Kitchen {
fun cook() = DEFAULT_FOOD
}
인터페이스를 직접 만들었다면 해당 문제를 쉽게 찾아 수정할 수 있겠지만 이러한 문제가 외부 API에서 발생한다면 해결하기도 힘들고 사용하고 있는 개발자 입장에선 답답하겠죠. 따라서 리턴 타입은 외부에서 확인할 수 있게 명시적으로 지정해 주는 것이 좋습니다.
inferred 타입을 사용하면 프로젝트의 진전에 제한이 생기거나 예측하지 못한 결과를 낼 수 있으니 타입을 확실하게 지정해야 하는 경우에는 명시적으로 타입을 지정해야 한다는 원칙을 잊지말아야 합니다.
'Kotlin > 안전성, 가독성을 효과적인 향상시키는 사용법' 카테고리의 다른 글
👋Kotlin : 6️⃣사용자 정의 오류 보다는 표준 오류를 사용 (0) | 2022.03.04 |
---|---|
👋Kotlin : 5️⃣예외를 활용해 코드에 제한을 걸어라 (0) | 2022.03.03 |
👋Kotlin : 3️⃣최대한 플랫폼 타입 사용을 제한하라 (0) | 2022.03.01 |
👋Kotlin : 2️⃣변수의 스코프 최소화 (0) | 2022.03.01 |
👋Kotlin : 1️⃣가변성을 제한하라 (0) | 2022.02.28 |