프로그래밍코틀린 개발자, 주니어/미드 백엔드

코틀린에서 type inference(타입 추론)란 무엇인가요? 명시적 타입 지정을 요구할 때 메커니즘은 어떻게 작동하며 어떤 제한이 있나요?

Hintsage AI 어시스턴트로 면접 통과

답변.

문제의 역사: 코틀린은 원래 간결하지만 엄격하게 타입이 지정된 문법의 언어로 설계되었습니다. 가독성을 높이고 코드 중복을 줄이기 위해 강력한 type inference(타입 추론)가 구현되었습니다.

문제: 가끔 타입 선언이 불필요해져 코드를 복잡하게 만듭니다. 그러나 타입을 과도하게 생략하면 읽기가 어려워지고 컴파일러가 타입을 추론할 수 없을 때 오류가 발생할 수 있습니다.

해결책: 타입 추론은 컴파일러가 초기화 또는 컨텍스트에 따라 대부분의 타입을 자동으로 결정하게 해줍니다. 그러나 여전히 엄격한 타입 지정이 코드의 정확성을 제어합니다.

코드 예시:

val name = "Kotlin" // String, 자동으로 타입이 추론됨 var count = 5 // Int, 자동으로 타입이 추론됨 val items = listOf(1, 2, 3) // List<Int> // 타입 추론이 불가능할 경우 명시적 타입 지정을 요구함 val callback: (Int) -> Unit = { println(it) }

주요 특징:

  • 변수 또는 표현식의 타입은 초기화 또는 함수 호출의 컨텍스트에서 추론될 수 있습니다.
  • 항상 타입 추론이 가능한 것은 아닙니다: 표현식이 모호한 경우 컴파일러는 명시적 선언을 요구합니다.
  • 타입 추론은 공공 함수 및 속성의 반환 타입에 적용되지 않습니다: ABI 안정성을 위해 컴파일러가 명시적으로 지정할 것을 요구합니다.

함정 질문.

공공 함수에서 반환 값의 타입을 명시하지 않을 수 있나요?

아니요, 함수가 공공인 경우, 컴파일러는 인터페이스의 안정성과 Java 상호 운용성을 지원하기 위해 반환 타입의 명시적 선언을 요구합니다.

예시:

// 오류! public fun compute(x: Int) = x * 2 // 명시적 필요: public fun compute(x: Int): Int = x * 2

val x = null의 타입은 무엇인가요?

컴파일러는 null이 컨텍스트 없이 타입을 가지지 않기 때문에 타입을 추론할 수 없습니다. 타입을 명시적으로 선언해야 합니다:

val x: String? = null

type inference가 컬렉션의 체인 처리에서 복잡한 제네릭 타입을 처리할 수 있나요?

네, 그러나 타입을 명확히 추론할 수 없는 경우(예: map이 타입을 변환함) 때때로 변수 타입을 명시해야 할 수 있습니다:

val values = listOf("1", "2").map { it.toInt() } // List<Int>, 타입이 추론됨

일반적인 오류 및 안티 패턴

  • 공공 API 함수에서 명시적 타입의 부재
  • 읽기를 어렵게 만드는 암시적 타입으로 코드의 과중함
  • null을 통해 초기화할 때 타입을 추론하려고 할 때의 오류

실제 사례

부정적 경우

프로젝트에서 모든 변수가 타입 없이 선언되어 있어 다른 개발자나 새로운 직원들이 코드를 탐색하고 이해하기 어렵습니다.

장점:

  • 코드가 줄어들음
  • 작성 및 리팩토링이 더 빠름

단점:

  • 읽고 유지하기 어려움
  • 초기화 변경 시 실수할 수 있음

긍정적 경우

함수 내부에서는 변수의 타입이 자동으로 추론되지만 모든 공공 API에서는 항상 반환 타입 및 매개변수 타입이 명시적으로 선언됩니다.

장점:

  • 코드 탐색이 용이함
  • 공공 메서드의 계약이 명확하게 고정됨

단점:

  • 복잡한 제네릭 타입의 경우 특히 약간 더 많은 코드가 필요함