Kotlin 脚本是一种无需事先编译或打包成可执行文件即可将 Kotlin 代码作为脚本执行的技术。此外,还有几种扩展机制,方便将 Kotlin 用于特定应用,例如配置构建工具。此外,Kotlin 提供了与脚本密切相关的 REPL 功能,以多种形式存在(例如,Kotlin Notebook)。
Kotlin 官方发布了一篇《State of Kotlin Scripting 2024》,介绍了 Kotlin 脚本当前的情况。
简单来说,Kotlin 脚本仍然是 Kotlin 基础架构的重要组成部分,官方将继续在实验状态下支持它。以下是正文要点:
Kotlin 脚本的演变
脚本功能早在Kotlin中被引入,作为一种实验,用于探索使用语言的新方式。从那时起,开发工作一直受到外部和内部用户需求的推动,以及我们团队内部一些实验的影响。随着时间的推移,我们在代码库中积累了很多与脚本相关的功能,而支持这些功能所需的努力也显著增加。因此,在某个时间点,我们开始审查现有功能,它们在JetBrains内外是如何使用的,以及我们如何将其提炼为一个合理的小集合,以便能够支持和发展,同时不打破太多现有用例。
基本脚本
我们对过去的脚本使用情况进行了研究,并得出结论,除了少数主要采用,例如 Gradle 构建脚本,已知的脚本和 REPL 的用途相对较少。这可能归因于各种因素,但结果依然清晰:其功能并不如我们预期的那么受欢迎。
一些技术问题可以(也将会)得到解决,但试图将 Kotlin 定位为一种脚本语言存在一些固有的问题。
特别是,Kotlin 不是一种解释性语言,因此无法实现专门脚本语言典型的用户体验。为了达到当前类似脚本的行为,我们在后台编译代码。编译过程非常密集,因为 Kotlin 编译器并未针对这种场景进行设计。
这就是为什么我们做出以下决定:
尽管我们将继续提供对 Kotlin 脚本的一般支持,包括基本 .kts 文件的编译和评估,以及自定义脚本(关于这一点将在下文中详细介绍),但我们并不准备推荐 Kotlin 脚本作为一种通用应用的脚本解决方案,例如,替代 Bash 或 Python。
另一方面,我们相信还有许多新的使用场景,在这些场景中,尽管存在已知限制,Kotlin 脚本仍然可能带来好处。还有几个其他潜在用例,我们希望进一步探索。
自定义脚本类型
最强大的脚本解决方案需要扩展机制,以便定制脚本的编译和评估。其中一个最显著的例子是 Gradle Kotlin DSL,它使用自定义脚本 API 将 Kotlin 语言与传统的 Gradle DSL 结合在一起构建脚本。这引出了第二个决定:
我们将继续支持自定义脚本 API(这是一个用于定制脚本编译和评估的一组 API 的非官方名称,以及嵌入第三方应用程序中的脚本主机的 API)。然而,这带来了一些警示:
- 它将保持在实验状态,并且可能永远不会成为 Kotlin 生态系统中稳定的一部分。所以,像文档和 IDE 支持通用自定义脚本支持这样的事情可能会持续滞后。
- 我们正在集中精力改善用户体验,针对一些已知用例,如 Gradle Kotlin DSL 和其他选择。这意味着我们可能无法分配足够的资源来支持一般情况。
Main.kts
除了基本和自定义脚本,我们希望继续支持 .main.kts 脚本。.main.kts 脚本最初是为了演示自定义脚本 API 的实用性而开发的。然而,由于它对依赖项和其他功能的支持,它被许多用户作为默认的 Kotlin 脚本解决方案采用。因此,下一步的决定是:
我们将继续开发 .main.kts 脚本类型,这对于简单的自动化任务已经非常有帮助。我们计划扩展其功能并简化 IDE 支持。这种脚本在 Kotlin 编译器和 IntelliJ IDEA 的 Kotlin 插件中仍然得到开箱即用的支持。
Kotlin REPL
默认的 REPL 实现自首次发布以来一直是 Kotlin 编译器(kotlinc)和 IntelliJ IDEA 的 Kotlin 插件的一部分。然而,这一功能受到限制,改进它从未成为团队的优先事项。因此,用户体验与 IntelliJ IDEA 中的整体 Kotlin 用户体验不相称。我们曾多次尝试推出替代性 REPL 实现(例如 Kotlin 交互式 Shell),但遗憾的是,这些项目始终没有获得足够的关注。
与此同时,我们正在改进 IntelliJ IDEA 的 Kotlin Notebook 插件,它提供了一个流畅、广泛且互动性强的 Kotlin 工作体验。使用 Kotlin Notebook,您可以开发和实验 Kotlin 代码,立即接收输出并可视化数据。我们相信这将是当前所有 REPL 解决方案的优秀替代品。
此外,IntelliJ IDEA 提供了 Kotlin Scratch 文件,在这些文件中您可以快速原型设计您的代码。因此:
我们计划停止在 Kotlin 编译器和 IntelliJ IDEA 插件中的默认 REPL 实现。
CLI REPL(通过 kotlinc)将在至少直到 Kotlin 2.3 发布之前继续运行,但其操作将仅限于兼容模式,即需要设置 -language-version 1.9 选项(并可能要求在发布版本 2.2 开始时使用一种选择标志)。 IntelliJ IDEA 插件中的默认 Kotlin REPL 将在下一个 IntelliJ IDEA 发布版中被移除。 我们将继续推广用于交互式 Kotlin 开发的 kotlin notebook 插件和 IDE Scratch 文件作为解决方案。
这一决定给外部 REPL 实现带来了不确定性,例如Kotlin交互式Shell。尽管我们计划在编译器和自定义脚本 API 中保留一些与REPL相关的功能(尤其是因为像Kotlin Notebook这样的解决方案依赖于它们),但随着最终切换到 K2 编译器,这些功能中的很大一部分将会改变或被删除,因此可能需要大量努力来重写此类实现以适应更改后的API。
基于 Kotlin 脚本的其它技术
除了这些主要领域,我们目前还支持一些其它相关的脚本技术和API。我们相信上述明确提到的案例涵盖了大多数用户需求。因此,我们计划从编译器和IntelliJ IDEA中删除大多数与脚本相关的组件和库。特别是:
- JSR-223 支持 – 考虑到原始 JSR 已经处于撤回状态,我们认为支持这个实际上已经过时的API没有意义。现有实现将继续运行,至少在Kotlin 2.3 的语言版本1.9兼容模式发布之前(但我们可能会考虑重命名该工件以提高对计划变更的认识),之后将被移除。
KotlinScriptMojo– 一个支持在Maven构建期间执行脚本的Maven插件。我们没有发现足够使用证据来维持它,因此计划在下一个Kotlin版本中删除它。kotlin-scripting-ide-services– 用于实现代码完成功能的库,主要针对REPL实现。目前用于像Kotlin Interactive这样的项目。这 heavily 基于前 K2 编译器的基础设施,并且不易移植到 K2 版本。因此,它很可能将在 Kotlin 2.3 发布时停止工作并将从代码库中移除。未来我们可能会考虑在 K2 的基础上重新实现类似功能,但目前这不是我们的重点追求方向。
暂无更多评论