코틀린은 원래 자바의 안전하고 간결한 대안으로 설계되었습니다. 그의 강력한 특징 중 하나는 타입 추론 메커니즘으로, 이는 타이핑 손실 없이 더 적은 단어로 코드를 작성할 수 있게 해줍니다. 타입 추론은 함수형 언어(예: 스칼라 및 해스켈)와 현대의 정적 타입 언어 설계 트렌드에 영감을 받았습니다.
자바 및 기타 정적 언어에서는 타입을 명시적으로 지정해야 하므로 코드가 과다하게 됩니다. 그러나 명시적 타입이 없으면 코드 이해가 어려워지고 타입 추론이 제대로 작동하지 않을 경우 불명확한 오류로 이어질 수 있습니다.
코틀린에서는 컴파일러가 종종 문맥에 따라 변수나 표현식의 타입을 스스로 결정할 수 있습니다. 이는 변수, 함수의 반환 값 및 람다 표현식 내부에서 작동합니다. 그러나 명시적 타입 지정을 요구하는 상황도 있습니다. 예를 들어 클래스 내에서 반환 값이 없는 함수 선언('fun doSomething()')을 할 때나 표현식이 모호한 경우입니다.
코드 예시:
val a = 42 // Int val s = "hello" // String fun sum(x: Int, y: Int) = x + y // 반환 타입 Int가 자동으로 추론됨 val list = listOf(1, 2, 3) // List<Int> // 값이 추론될 수 없는 경우 명시적 타입 지정이 필요함 val emptyList: List<String> = emptyList() // 그렇지 않으면 List<Nothing>이 됨
주요 특징:
왜 클래스의 속성에 대해 콜론 뒤에 타입을 항상 생략할 수 없나요?
선언 위치에서 초기화되지 않는 속성(예: 게터를 통해 또는 init 블록에서)의 경우, 컴파일러는 초기화자를 볼 수 없기 때문에 타입을 자동으로 추론할 수 없습니다.
class User { val fullName: String // 반드시 타입을 명시해야 하며, 그렇지 않으면 오류 get() = "name" }
명시적인 타입 없이 emptyList()를 사용하면 변수의 타입은 무엇인가요?
이 경우 List<Nothing> 타입이 추론되어 결과는 거의 유용하지 않게 됩니다.
val list = emptyList() // List<Nothing>
함수의 파라미터에 대해 타입 추론이 작동하지 않는 경우는 언제인가요?
함수의 시그니처에서는 항상 파라미터 타입을 명시해야 하며, 그렇지 않으면 컴파일러는 오류를 발생시킵니다.
// 오류: // fun foo(x) = x * 2 // 올바른 경우: fun foo(x: Int) = x * 2
개발자가 명시적 타입을 지정하지 않고 API 함수에서 값을 반환하기 위해 emptyList()를 사용합니다. 그 결과 List<Nothing> 타입이 되어 이 API와 작업할 때 문제가 발생합니다.
장점:
개발자는 빈 컬렉션 작업 시 항상 명시적 타입을 지정하고, 이를 통해 가독성이 향상될 수 있는 경우에만 그러하며, 그렇지 않은 경우에는 컴파일러의 타입 추론에 의존합니다.
장점: