Search

Opt-in requirements

Kotlin 표준 라이브러리는 특정 API 요소 사용 시 명시적인 동의를 요구하는 메커니즘을 제공한다.
이 메커니즘을 통해 라이브러리 개발자는 사용자가 실험적인 상태에 있는 API를 사용할 때 발생할 수 있는 문제점에 대해 경고하고 API의 사용이 미래에 변경될 가능성이 있음을 알릴 수 있다.
문제가 발생하는 것을 방지하기 위해 컴파일러는 이러한 API 사용에 대해 경고를 하고 사용자가 동의한 후에만 API를 사용할 수 있도록 요구한다.

API 사용에 대한 동의

라이브러리 작성자가 라이브러리 API의 선언에 대해 사용자가 동의해야 한다고 표시한 경우 코드에서 이를 사용하려면 명시적으로 동의해야 한다.
동의하는 방법은 여러 가지가 있으며 기술적인 제한 없이 상황에 맞게 선택할 수 있다.

동의 전파

// 라이브러리 코드 @RequiresOptIn(message = "이 API는 실험적입니다. 예고 없이 변경될 수 있습니다.") @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) annotation class MyDateTime // 동의 요구 주석 @MyDateTime class DateProvider // 동의를 요구하는 클래스 // 클라이언트 코드 fun getYear(): Int { val dateProvider: DateProvider // 오류: DateProvider는 동의를 요구합니다. // ... } @MyDateTime fun getDate(): Date { val dateProvider: DateProvider // OK: 이 함수도 동의를 요구합니다. // ... } fun displayDate() { println(getDate()) // 오류: getDate()는 동의를 요구합니다. }
Kotlin
복사
다른 사용자들이 사용할 라이브러리 코드에서 해당 API를 사용해야 하는 경우 동의 요구를 자신이 작성하는 API로 전파할 수 있다.
이를 위해 사용하는 API의 동의 요구 주석인 @RequiresOptIn 을 자신의 선언에 추가하면 된다.
이를 통해 해당 API 요소를 사용하면서도 동의 요구를 API 사용자에게 전달할 수 있다.
// 클라이언트 코드 fun getDate(dateProvider: DateProvider): Date { // 오류: DateProvider는 동의를 요구합니다. // ... } fun displayDate() { println(getDate()) // 경고: getDate()의 시그니처에 DateProvider가 포함되어 있으며, 이는 동의를 요구합니다. }
Kotlin
복사
동의가 필요한 API를 암묵적으로 사용하는 경우에도 동의가 필요하다.
API 요소에 동의 요구 주석이 없더라도 해당 API의 시그니처에 동의를 요구하는 타입이 포함되어 있다면 경고가 발생한다.
여러 동의 요구가 있는 API를 사용할 경우 해당 요구 주석들을 모두 선언에 추가해야 한다.

동의 요구를 전파하지 않기

// 라이브러리 코드 @RequiresOptIn(message = "이 API는 실험적입니다. 예고 없이 변경될 수 있습니다.") @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) annotation class MyDateTime // 동의 요구 주석 @MyDateTime class DateProvider // 동의를 요구하는 클래스 // 클라이언트 코드 @OptIn(MyDateTime::class) fun getDate(): Date { // DateProvider를 사용하지만 동의 요구를 전파하지 않음 val dateProvider: DateProvider // ... } fun displayDate() { println(getDate()) // OK: 동의가 필요하지 않음 }
Kotlin
복사
라이브러리처럼 외부에 API를 노출하지 않는 모듈에서는 동의 요구를 전파하지 않고도 API를 사용할 수 있다.
이 경우 선언에 @OptIn 주석을 추가하고 동의 요구 주석을 인수로 전달하면 된다.
@OptIn(MyDateTime::class) fun getDate(dateProvider: DateProvider): Date { // DateProvider가 시그니처에 포함되어 동의 요구가 전파됨 // ... } fun displayDate() { println(getDate()) // 경고: getDate()는 동의를 요구합니다. }
Kotlin
복사
그러나 함수 시그니처에 동의를 요구하는 타입이 포함된 경우에는 여전히 동의 요구가 전파된다.
@file:OptIn(MyDateTime::class)
Kotlin
복사
모든 함수와 클래스에서 동의 요구를 사용하려면 파일 상단에 파일 레벨 주석인 @file:OptIn 을 추가할 수 있다.

모듈 전체 동의

// Gradle을 사용하는 경우 다음과 같이 설정할 수 있다. import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask tasks.named<KotlinCompilationTask<*>>("compileKotlin").configure { compilerOptions.freeCompilerArgs.add("-opt-in=org.mylibrary.OptInAnnotation") }
Kotlin
복사
모듈 전체에서 동의를 요구하는 API를 사용하려면 -opt-in 컴파일 옵션을 사용하여 전체 모듈에 동의할 수 있다.
이를 통해 모듈 내 모든 선언이 @OptIn 주석을 사용하는 것과 동일한 효과를 얻는다.

API에 대해 동의 요구하기

동의 요구 주석 만들기

@RequiresOptIn @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) annotation class MyDateTime
Kotlin
복사
모듈 API 사용에 대해 명시적인 동의를 요구하려면 동의 요구 주석으로 사용할 주석 클래스를 생성해야 한다.
이 클래스는 @RequiresOptIn 으로 주석 처리되어야 한다.
동의 요구 주석은 몇 가지 요구 사항을 충족해야 한다.
BINARY 또는 RUNTIME 유지
EXPRESSION, FILE, TYPE 또는 TYPE_PARAMETER는 대상에 포함되지 않아야함
매개변수를 가질 수 없음
동의 요구는 두 가지 심각도 수준 중 하나를 가질 수 있다.
RequiresOptIn.Level.ERROR
기본값
동의가 필수이다.
동의하지 않으면 해당 API를 사용하는 코드가 컴파일되지 않는다.
RequiresOptIn.Level.WARNING
동의가 필수가 아니지만 권장된다.
동의하지 않으면 컴파일러가 경고를 발생시킨다.
@RequiresOptIn(level = RequiresOptIn.Level.WARNING, message = "이 API는 실험적입니다. 향후 호환되지 않게 변경될 수 있습니다.") @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) annotation class ExperimentalDateTime
Kotlin
복사
원하는 수준을 설정하려면 @RequiresOptIn 주석의 level 매개변수를 지정하면 된다.
추가적으로 API 사용자가 API 사용 시 특별한 조건에 대해 알릴 수 있는 메세지를 제공할 수 있다.
이 메세지는 동의 없이 API를 사용하는 사용자에게 컴파일러가 표시한다.
여러 독립적인 기능을 배포할 경우 각 기능에 대해 동의 요구 주석을 선언하는 것이 좋다.
이렇게 하면 클라이언트가 명시적으로 수용한 기능만 사용할 수 있으므로 API 사용이 더 안전해진다.
또한 각 기능에 대한 동의 요구를 독립적으로 제거할 수 있다.

API 요소에 주석 추가하기

@MyDateTime class DateProvider @MyDateTime fun getTime(): Time {}
Kotlin
복사
API 요소 사용에 대해 동의를 요구하려면 해당 선언에 동의 요구 주석을 추가한다.
일부 언어 요소에 대해서는 동의 요구 주석을 적용할 수 없다는 점에 유의해야 한다.
프로퍼티의 백킹 필드나 getter에는 주석을 달 수 없고 프로퍼티 자체에만 주석을 달 수 있다.
로컬 변수나 값 매개변수에는 주석을 달 수 없다.

안정화 이전 API에 대한 동의 요구

@Deprecated("이 동의 요구는 더 이상 사용되지 않습니다. 코드에서 제거하십시오.") @RequiresOptIn annotation class ExperimentalDateTime
Kotlin
복사
안정되지 않은 기능에 대해 동의 요구를 사용하는 경우 API의 졸업 과정을 신중하게 처리하여 클라이언트 코드가 깨지지 않도록 해야 한다.
예비 안정 상태에 있는 API가 졸업하여 안정 상태로 출시되면 해당 선언에서 동의 요구 주석을 제거해야 한다.
그러면 클라이언트는 제한 없이 이를 사용할 수 있다.
그러나 기존 클라이언트 코드와의 호환성을 유지하기 위해 주석 클래스는 모듈에 남겨 두어야 한다.
API 사용자에게 모듈을 업데이트하도록 알리려면(주석을 제거하고 다시 컴파일) 주석을 @Deprecated 로 표시하고 폐기 메세지에 설명을 제공해야 한다.
이렇게 하면 동의 요구가 사라진 경우에도 클라이언트 코드가 여전히 호환성을 유지할 수 있다.