如果你在代码中使用了某个 API, 而你的代码本身又打算给第三方使用(是一个库), 那么你也可以将这个的 API 的要求使用者同意设定传递给你的 API. 为了做到这一点, 需要将你的函数体中使用到的 API 的 明确要求使用者同意(Opt-in Requirement) 注解 添加到你的函数的声明部分. 这样你就可以使用要求使用者同意的 API 元素了.
// 库代码
@RequiresOptIn(message = "This API is experimental. It may be changed in the future without notice.")
@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() 要求使用者同意
}
在上面的示例中我们可以看到, 被注解的函数变得象是 @MyDateTime API 的一部分. 因此, 这种对使用者同意的强制要求传递到了使用 API 的代码中; 使用这段代码的其他代码也会看到同样的编译警告, 并要求须明确同意使用.
隐含使用要求使用者同意的 API, 本身也需要使用者同意. 如果一个 API 元素没有要求使用者同意注解, 但它的签名包含了要求使用者同意的类型, 那么使用这个 API 仍然会产生警告. 请看下面的例子.
// 库的使用者代码
fun getDate(dateProvider: DateProvider): Date { // 编译错误: DateProvider 要求使用者同意
// ...
}
fun displayDate() {
println(getDate()) // 编译警告: getDate() 的签名包含了 DateProvider, 这个类型要求使用者同意
}
// 库代码
@RequiresOptIn(message = "This API is experimental. It may be changed in the future without notice.")
@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: 不需要使用者同意
}
当使用者调用 getDate() 函数时, 他们不会由于这个函数内部使用的 API 而被被警告说需要明确同意.
此外, 你还可以指定一个 message 来提示 API 使用者关于这个 API 的特定条件. 对于使用这个 API 但没有明确同意的用户, 编译器会显示提示这个警告信息.
@RequiresOptIn(level = RequiresOptIn.Level.WARNING, message = "This API is experimental. It can be incompatibly changed in the future.")
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
annotation class ExperimentalDateTime