[中文正文内容]

Crystal 1.16.0 is released!

2025年4月9日

Johannes Müller

API 文档 变更日志 源码

我们很高兴地宣布 Crystal 1.16.0 版本发布,其中包含多项新特性和 Bug 修复。

预构建包已在 GitHub Releases 和我们的官方分发渠道上提供。请参阅 crystal-lang.org/install 获取安装说明。

统计

此版本包含了自 1.15.1 以来的 162 项变更,由 19 位贡献者完成。感谢所有贡献者为改进该语言所做的努力!❤️

变更

下面我们列出该语言、编译器和标准库中最值得关注的变更。有关更多详细信息,请访问 完整变更日志

破坏性变更

以下变更会破坏编译器之前的行为,但我们希望它们不会对现有代码造成太大影响。如果并非如此,请在 issue tracker论坛 中告知我们。

修复了 File.match? 的实现

[File.match?](https://crystal-lang.org/api/1.16.0/File.html#match%3F(pattern%3AString%2Cpath%3APath|String)%3ABool-class-method>) 的实现不够完善,已替换为新的算法。此更改不应影响任何先前按文档记录正常工作的行为。

修正实现中的错误会导致观察到的行为发生以下变化:

注意:[Dir.glob](https://crystal-lang.org/api/1.16.0/Dir.html#glob(patterns:Enumerable,match:File::MatchOptions=File::MatchOptions.glob_default,follow_symlinks:Bool=false):Array(String)-class-method>) 的实现方式不同,不受该无效行为的影响。它没有发生任何变化。

感谢,@straight-shoota

参数名称后缀已弃用

用于 defs、macros 和 blocks 的参数名称的后缀 ?! 已弃用。这使它们与其他变量名保持一致。现在它们会产生警告 (#12197)。

感谢,@potomak

Enumerable#sum#product 的隐式返回类型

当元素类型是 union 时,[Enumerable#sum](https://crystal-lang.org/api/1.16.0/Enumerable.html#sum-instance-method>) 和 [#product](https://crystal-lang.org/api/1.16.0/Enumerable.html#product-instance-method>) 不再解析隐式返回类型。这无法可靠地工作。相反,您需要通过带有预期返回类型值的 initial 参数显式指定 sum/product 类型 (#15314)。实际上,这会将运行时错误条件转换为编译时错误。

# Crystal 1.16.0
[1, 10000000000_u64].sum # Error: `Enumerable#sum` and `#product` do not support Union types.
             # Instead, use `Enumerable#sum(initial)` and `#product(initial)`,
             # respectively, with an initial value of the intended type of the call.
# Crystal < 1.16.0
[1, 10000000000_u64].sum # OverflowError: Arithmetic overflow
# Passing an explicit initial value works, before and after:
[1, 10000000000_u64].sum(0_u64) # => 10000000001_u64

感谢,@rvprasad

HTTP::Request 中的资源字符串

修复了 [HTTP::Request](https://crystal-lang.org/api/1.16.0/HTTP/Request.html#-instance-method>),以正确解析看起来像绝对 URL 的 HTTP 资源字符串。这可能会破坏依赖于先前错误行为的代码 (#15499)。

# Crystal 1.16.0
HTTP::Request.new("GET", "http://example.com/foo").path # => "http://example.com/foo"
# Crystal < 1.16.0
HTTP::Request.new("GET", "http://example.com/foo").path # => "/foo"

感谢,@straight-shoota

子命令的环境变量变更

当为子命令运行进程时,编译器不会设置环境变量 $CRYSTAL。此变量仅在 1.14.0 中的 #14953 中引入。我们添加了一个更灵活的替代方案 $CRYSTAL_EXEC_PATH,并且等效于 $CRYSTAL 的现在是 $CRYSTAL_EXEC_PATH/crystal。编译器还会将其路径添加到 $PATH (#15186)。

感谢,@straight-shoota

Execution Contexts (执行上下文)

来自 RFC 0002 的 Execution Contexts 作为一个预览功能提供。它已经被证明相当强大,但可能存在一些粗糙的边缘。

您可以使用编译器标志 -Dpreview_mt -Dexecution_context 测试 Execution Contexts。默认上下文是单线程的(与独立的 -Dpreview_mt 不同)。但是您可以根据需要启动其他上下文(例如,[Fiber::ExecutionContext::MultiThreaded](https://crystal-lang.org/api/master/Fiber/ExecutionContext/MultiThreaded.html>) 或 [Fiber::ExecutionContext::Isolated](https://crystal-lang.org/api/master/Fiber/ExecutionContext/Isolated.html>))。

mt_context = Fiber::ExecutionContext::MultiThreaded.new("worker-threads", 4)
10.times do
 mt_context.spawn do
  do_something
 end
end
gtk = Fiber::ExecutionContext::Isolated.new("Gtk") do
 Gtk.main
end
gtk.wait

Execution Contexts 在大多数目标上都受支持,包括 Linux、macOS、Windows 和不同的 BSD,以及 X86 和 ARM 架构。这一新增功能标志着 持续改进多线程支持的项目 的顶峰,该项目得到了 84codes 的帮助。

语言

感谢,@HertzDevil

感谢,@HertzDevil

标准库

感谢,@HertzDevil

感谢,@punteek

感谢,@ysbaddaden

编译器

感谢,@HertzDevil, @straight-shoota

感谢,@HertzDevil

编译器工具

文档生成器可以选择包含 privateprotected 对象,以及 lib bindings (libfununioncstructexternaltype) 中的对象,如 RFC 0011 中所提议的那样。:showdoc: 指令启用该功能。

# :showdoc:
#
# Documentation for LibFoo
lib Foo
 # Documentation for function foo
 fun foo : Void
end
# :showdoc:
#
# Documentation for method bar
private def bar
end

Thanks@nobodywasishere

依赖更新

感谢,@HertzDevil

弃用

感谢

感谢 84codes 和其他所有 赞助商 的持续支持,我们才能够完成所有这些工作。为了保持并提高开发速度,捐款和赞助至关重要。OpenCollective 可用于此目的。

如果您想成为直接赞助商或找到其他支持 Crystal 的方式,请联系 crystal@manas.tech。我们提前感谢您!

贡献