프로그래밍미들 코틀린 개발자

코틀린에서 속성 делегирование은 어떻게 구현되어 있습니까? 메커니즘, 장점, 제한 사항을 설명하고 자세한 예를 제시하십시오.

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

답변

코틀린은 delegated properties에 대한 내장 지원을 제공합니다. by 메커니즘은 속성의 getter/setter를 특정 객체인 위임자에게 위임할 수 있게 해줍니다. 가장 잘 알려진 위임자에는 lazy, observable, vetoable 및 사용자 정의가 있습니다.

장점:

  • 데이터 소유 논리를 재사용할 수 있음
  • 지연 초기화, 캐싱, 접근 제어, 로깅 등의 패턴을 쉽게 구현할 수 있음
  • 더 깔끔하고 선언적인 코드

사용자 정의 위임자 예제:

class UpperCaseDelegate { private var value: String = "" operator fun getValue(thisRef: Any?, property: KProperty<*>): String = value operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) { value = newValue.uppercase() } } class Person { var name: String by UpperCaseDelegate() }

제한 사항:

  • 위임은 클래스 속성에서만 작동합니다 (top-level 변수/객체 속성에서는 작동하지 않음)
  • (위임자가 직렬화할 수 없는 필드를 포함하는 경우) 직렬화와 관련된 문제 발생 가능성 있음

트릭 질문

Context(예: Android Context)에 접근해야 하는 위임자를 companion 객체나 최상위 객체 속성에서 사용할 수 있습니까?

종종 "가능하다, 왜 안되겠는가?"라는 잘못된 대답을 합니다.

정답: 아니요, companion 객체와 최상위 객체는 클래스 인스턴스나 애플리케이션 초기화 전에 초기화되므로 초기화되지 않은 컨텍스트에 접근할 수 있는 오류가 발생할 수 있습니다. 인스턴스에 접근해야 하는 위임자는 클래스 속성에서만 사용해야 합니다.

주제에 대한 미숙지로 인한 실제 오류 사례


사례

Android-ViewModel에서 지연 초기화 위임: 프로그래머는 heavy-lazy 위임자를 companion 객체로 옮겼습니다. 특정 상황에서(SDK 업데이트 후) 애플리케이션이 초기화 중에 충돌하기 시작했습니다 - 컨텍스트가 아직 사용 가능하지 않았지만 위임자는 이미 자신의 "init"을 수행했습니다.


사례

위임자를 통한 잘못된 직렬화: 데이터를 저장하기 위해 사용자 정의 위임자를 사용했으나, 이 위임자는 컨텍스트에 대한 직렬화할 수 없는 참조를 포함하고 있었습니다. 직렬화 시도를 할 때 오류가 발생하고 데이터가 손실되었습니다.


사례

잘못된 콜백을 가진 Observable 위임자: 개발자는 상태 모니터링을 위해 Delegates.observable을 사용했으며, 람다 내에서 새로운 값을 할당하면서 루프와 StackOverflowError가 런타임에 발생했습니다.