이펙티브 코틀린 item4: inferred 타입으로 리턴하지 말라

woga·2023년 2월 19일
0

코틀린 공부

목록 보기
6/54
post-thumbnail

코틀린의 타입 추론 (type inference)은 JVM 세계에서 가장 널리 알려진 코틀린의 특징이다. (물론 자바도 자바 10부터 코틀린을 따라 도입하긴 했지만 코틀린과 비교하면 제약이 있다)

다만, 타입 추론을 사용할 때는 몇 가지 위험한 부분들이 있다. 그래서 이런 위험한 부분을 피하려면 정확하게 오른쪽 피연산자에 맞게 설정을 해야한다. 슈퍼클래스 또는 인터페이스로는 절대 설정되지 않는다.

open class Animal
class Zebra: Animal()

fun main() {
	var animal = Zebra()
    animal = Animal() // type mismatch
}

아래와 같이 타입을 명시적으로 지정하자

open class Animal
class Zebra: Animal()

fun main() {
	var animal: Animal = Zebra()
    animal = Animal()
}

물론 이렇게 간단하게 지정하는 건 직접 라이브러리(또는 모듈)를 조작할 수 없는 경우에는 이러한 문제를 간단하게 해결할 수 없다. 그리고 여기서 inferred 타입을 위험하다

interface CarFactory {
	fun produce(): Car
}

그리고 아래와 같이 디폴트로 생성되는 자동차가 있다고 보자

val DEFAULT_CAR: Car = Fiat126P()

그러다가 이 디폴트카가 이미 Car 명시적으로 지정되어 있어서 함수의 리턴 타입을 제거했다고 하자

그리고 이후에 다른 사람이 코드를 보다가, DEFAULT_CAR는 타입 추론에 의해 자동으로 타입이 지정될 것이므로, Car를 명시적으로 지정하지 않아도 된다고 생각해서 또 코드를 아래와 같이 변경했다

val DEFAULT_CAR = Fiat126P()

interface CarFactory {
	fun produce() = DEFAULT_CAR
}

이 코드는 잘 작동할까?
아니다
결국 CarFactory에서는 이제 Fiat126P 이외의 자동차를 생산하지 못하는 문제가 발생한다.
만약 이 인터페이스를 우리가 만들었으면 이슈 파악은 쉬울 것이다.
그러나 외부 API(모듈, 코드의 일부에서 사용될 가능성이 있는 클래스, 함수, 객체)라면 문제를 쉽게 해결할 수 없다.

그러므로 리턴 타입은 API를 잘 모르는 사람에게 전달해 줄 수 있는 중요한 정보이다. 꼭 외부에서 확인할 수 있게 지정해주자!!

또한 안전을 위해서 지정한 타입이 있다면 특별한 이유와 확실한 확인 없이는 제거하지 말자. Inferred 타입은 프로젝트가 진전될 때, 제한이 너무 많아지거나 예측하지 못한 결과를 낼 수 있다.

profile
와니와니와니와니 당근당근

0개의 댓글