【问题标题】:How to avoid `@KtorExperimentalAPI` propagating everywhere?如何避免`@KtorExperimentalAPI` 到处传播?
【发布时间】:2021-01-05 10:15:10
【问题描述】:

我可以在 Ktor 1.4.X 中看到这一点,例如io.ktor.config.ApplicationConfig 被标记为@KtorExperimentalAPI,因此任何调用它的东西也需要标记为@KtorExperimentalAPI

编辑添加:在 Ktor 1.5.0 中,io.ktor.config.ApplicationConfig 不再需要 @KtorExperimentalAPI,因此目前最好的解决方法是升级 Ktor 版本。

但这在本质上是传播的。如果我实现了一个实用函数,它需要一个应用程序配置参数,因此调用了实验性的Application.environment.config.property(path) API,这个实用函数也必须标记为@KtorExperimentalAPI。林斯,重复。很快,我的应用程序中的所有内容都被标记为 @KtorExperimentalAPI,因为在实现的某个地方(调用 API)* 调用了实验性 API。

有没有办法“封装不良”:调用实验性 API 并在那里做一些魔术,这样@KtorExperimentalAPI 就不会成为病毒并需要传播到应用程序的其余部分?

例如:

// I can accept that this perhaps
// needs to be marked @KtorExperimentalAPI 
@KtorExperimentalAPI
fun Application.configProperty(path: String) : String {
    return environment.config.property(path).getString()
}

// But I want to avoid that everything that calls it also
// needs to be marked @KtorExperimentalAPI
fun Application.getFoobarProperty() : String {
    return "${configProperty("foo")}_${configProperty("bar")}";
}

【问题讨论】:

    标签: kotlin ktor


    【解决方案1】:

    您可以使用编译器参数将选择加入配置为模块范围。使用该编译器参数,您不必再使用注释。你可以在这里阅读更多信息:https://kotlinlang.org/docs/reference/opt-in-requirements.html#module-wide-opt-in

    如果您使用的是 Kotlin-Gradle,请将其添加到您的编译任务中:

    kotlinOptions.freeCompilerArgs += "-Xopt-in=io.ktor.util.KtorExperimentalAPI"
    

    如果您使用的是 Maven,请将此配置添加到 kotlin-maven-plugin:

    <configuration>
        <args>
            <arg>-Xopt-in=io.ktor.util.KtorExperimentalAPI</arg>
        </args>
    </configuration>
    

    【讨论】:

      【解决方案2】:

      感谢@marstran 的回答中提供的链接,我找到了我想要的东西:

      https://kotlinlang.org/docs/reference/opt-in-requirements.html#non-propagating-use

      它描述了如何做我想做的事:

      在不公开自己的 API 的模块(例如应用程序)中,您可以选择使用 API,而无需将选择加入要求传播到您的代码。在这种情况下,请使用 @OptIn 标记您的声明,并将选择加入要求注释作为其参数传递

      我最终得到:

      // Not @KtorExperimentalAPI, but:
      @OptIn(KtorExperimentalAPI::class)
      fun Application.configProperty(path: String) : String {
          return environment.config.property(path).getString()
      }
      

      确实需要将此添加到build.gradle.kts

      // This is to avoid having to add @KtorExperimentalAPI annotations all over the place
      tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
          kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-27
        • 1970-01-01
        • 2011-11-25
        • 2019-06-06
        • 2015-07-31
        • 2017-02-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多