代码之家  ›  专栏  ›  技术社区  ›  Peter V. Mørch

如何避免@KtorExperimentalAPI是递归的/“病毒性的”,并且在任何地方都需要?

  •  0
  • Peter V. Mørch  · 技术社区  · 4 年前

    我可以看到Ktor 1.4.X的情况,例如。 io.ktor.config.ApplicationConfig 已标记 @KtorExperimentalAPI ,因此任何调用它的东西也需要标记为 @Ktor实验API .

    已编辑以添加 在Ktor 1.5.0中, io.ktor.config。应用程序配置 不再需要 @Ktor实验API ,到目前为止,最好的解决方案是升级Ktor版本。

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

    有没有什么方法可以“封装不良”:调用实验性的API并在那里做一些魔术,这样 @Ktor实验API 不会变成病毒,需要传播到应用程序的其他部分吗?

    例如。:

    // 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")}";
    }
    
    1 回复  |  直到 4 年前
        1
  •  2
  •   Peter V. Mørch    4 年前

    您可以使用编译器参数将选择加入配置为模块范围。有了编译器参数,您就不必再使用注释了。您可以在此处阅读更多信息: 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
  •  0
  •   Peter V. Mørch    4 年前

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

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

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

    在不公开自己的API的模块(如应用程序)中,您可以选择使用API,而无需将opt-In要求传播到代码。在这种情况下,在传递选择加入需求注释作为参数时,用@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"
    }