시스템아 미안해
Chapter 2: Readability - Item 13: Consider making types explicit 본문
Chapter 2: Readability - Item 13: Consider making types explicit
if else 2026. 1. 25. 11:18Kotlin은 매우 뛰어난 타입 추론 시스템을 갖추고 있어, 개발자에게 명확한 경우에는 타입을 생략할 수 있게 해줍니다.
val num = 10
val name = "Marcin"
val ids = listOf(12, 112, 554, 997)
이러한 방식은 타입이 문맥상 분명하고, 추가적인 타입 명시가 불필요하거나 오히려 코드를 지저분하게 만드는 경우에 개발 속도뿐만 아니라 가독성까지 함께 향상시켜 줍니다.
다만 타입이 명확하지 않은 상황에서는 이러한 생략을 과도하게 사용해서는 안 됩니다.
val data = getSomeData()
우리는 코드를 가독성을 중심으로 설계해야 하며, 독자에게 중요한 정보를 숨겨서는 안 됩니다.
독자가 언제든지 함수 정의로 이동해 반환 타입을 확인할 수 있으니 반환 타입을 생략해도 된다는 주장은 타당하지 않습니다.
그곳에서도 타입이 추론되어 있을 수 있기 때문에, 개발자는 점점 더 깊은 곳으로 코드를 따라가야 하는 상황에 놓일 수 있습니다.
또한 코드를 GitHub와 같이 구현부로 바로 이동할 수 없는 환경에서 읽는 경우도 많습니다.
설령 이동이 가능하더라도, 우리의 작업 기억(working memory)은 매우 제한적이므로 이런 식으로 소모하는 것은 바람직하지 않습니다.
타입은 중요한 정보이며, 문맥만으로 명확하지 않다면 반드시 명시해 주어야 합니다.
val data: UserData = getSomeData()
명시적인 타입을 지정하는 것은 가독성을 높이기 위한 목적뿐만 아니라,
Item 3: 가능한 한 빨리 플랫폼 타입을 제거하라에서 보았듯이 안전성을 높이기 위한 목적도 있습니다.
타입은 개발자에게도, 컴파일러에게도 중요한 정보가 될 수 있습니다.
그렇다면 주저하지 말고 타입을 명시해야 합니다.
비용은 거의 들지 않지만, 얻을 수 있는 이점은 매우 큽니다.
이 규칙은 특히 공개 API에서 더욱 중요합니다.
공개 API를 설계할 때는 외부로 노출되는 타입을 항상 명시적으로 지정해야 합니다.
이는 가독성을 위해서도 중요하지만, 안전성을 위해서도 반드시 필요합니다.
이제 예제를 통해 이를 살펴보겠습니다.
먼저, Kotlin에서 타입 추론은 항상 가능한 한 가장 구체적인 타입을 선택한다는 점을 짚고 넘어가겠습니다.
그렇기 때문에 아래 예제에서 animal의 타입은 Bear가 되며, Camel은 여기에 할당될 수 없습니다.
open class Animal
class Bear : Animal()
class Camel : Animal()
fun main() {
var animal = Bear()
animal = Camel() // Error: Type mismatch
}
여러분은 클라이언트가 자동차 공장을 정의하고 자동차를 생성하는 데 사용하는 다음과 같은 인터페이스를 정의했습니다.
interface CarFactory {
fun produce(): Car
}
하지만 여러분의 나라에서 특히 인기가 많은 자동차 모델이 하나 있다는 사실을 알게 되었고,
그래서 이를 기본 자동차로 지정하기로 결정했습니다.
val DEFAULT_CAR: Car = Fiat126P()
이 자동차는 대부분의 공장에서 생산되기 때문에 기본값으로 설정했습니다.
또한 DEFAULT_CAR는 어차피 Car라고 판단하여, 타입을 추론에 맡겼습니다.
interface CarFactory {
fun produce() = DEFAULT_CAR
}
마찬가지로, 이후에 누군가가 DEFAULT_CAR를 살펴보고 그 타입 역시 추론할 수 있다고 판단했습니다.
val DEFAULT_CAR = Fiat126P()
이제 모든 공장은 오직 Fiat126P만 생산할 수 있게 되어 버렸습니다.
이는 결코 바람직한 상황이 아닙니다.
만약 이 인터페이스가 여러분 자신의 프로젝트 내부에서만 사용되었다면,
이 문제는 비교적 빠르게 발견되고 쉽게 수정되었을 가능성이 큽니다.
그러나 이 인터페이스가 외부에 공개된 API의 일부였다면,
여러분이 이 사실을 가장 먼저 알게 되는 방법은 아마도 분노한 사용자들의 항의였을 것입니다.
라이브러리 작성자를 위한 명시적 API 모드 (Explicit API mode for library authors)
Kotlin 1.4에서는 라이브러리 작성자를 위한 **명시적 API 모드(explicit API mode)**가 도입되었습니다.
이 모드를 활성화하면, Kotlin은 공개 API에 포함되는 모든 선언에 대해 타입과 가시성 지정자를 반드시 명시하도록 강제합니다.
이는 앞서 살펴본 예와 같은 실수를 방지하는 데 큰 도움이 되는 훌륭한 기능입니다.
또한 코드의 가독성을 향상시키는 데에도 매우 효과적인 방법입니다.
이 기능은 build.gradle 또는 build.gradle.kts 파일에서 다음과 같이 활성화할 수 있습니다.
kotlin {
// ...
// for strict mode
explicitApi()
// for warning mode
explicitApiWarning()
}