拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Crystal 1.21.0 全面解析:Execution Contexts 正式发布、PCRE 回退移除与 40+ 项新特性

Crystal 1.21.0 全面解析Execution Contexts 正式发布、PCRE 回退移除与 40 项新特性【免费下载链接】crystalThe Crystal Programming Language项目地址: https://gitcode.com/gh_mirrors/cr/crystalCrystal 1.21.0发布于 2026-07-16是本仓库 doc/changelogs/v1.21.md 记录的里程碑版本其中运行时 Execution Contexts 正式发布、文本处理默认移除对旧 PCRE 的自动回退同时带来语言层%W插值字符串数组字面量、TypeNode#all_methods、Socket#sendfile、UUID v6/v8 等大量新能力。阅读本文后你将掌握 1.21.0 的破坏性变更影响面、各模块新 API 的调用方式以及底层实现对应的源码位置可直接评估升级成本并上手新特性。一、版本概览与升级必读两大 Breaking Changes1.21.0 以两项破坏性变更拉开序幕升级前必须先确认这两点对你的项目是否有影响。1. Execution Contexts 正式发布运行时(runtime) Release: Execution ContextsPR [#17100]、[#17104]标志着执行上下文Fiber 调度基础设施经过长期打磨后正式转正。在此之前Fiber::ExecutionContext相关实现已沉淀在 src/fiber/execution_context/ 目录下含context.cr、stack.cr、stack_pool.cr等1.21.0 将其作为默认运行时正式发布不再视为实验特性。同版本还包含了多项围绕该特性的修复与兼容工作例如Fiber::ExecutionContext::Monitor兼容旧版 Crystal 编译出的程序[#17007]修复Fiber::ExecutionContext.current?[#17092]spawn(same_thread:)被标记为deprecated[#17097]配合 Execution Contexts 的正式化旧的同线程调度参数逐步退出历史舞台。从源码结构看src/fiber/execution_context/execution_context.crExecutionContext 是比旧 Fiber 栈模型更精细的调度单元抽象1.21.0 的发布意味着这一抽象成为官方推荐的并发基础设施。2. 文本处理不再自动回退到旧版 PCRE(text) Disable automatic fallback to legacyPCRE[#16924]是一个影响面较大的行为变更此前当 PCRE2 不可用时Crystal 的Regex会自动回退到旧版 PCRE1.21.0 起这一自动回退被关闭。这意味着构建或运行环境中缺少 PCRE2 时依赖正则表达式的代码将不再静默降级升级后若发现正则相关报错应首先检查运行环境是否提供 PCRE2 库。正则模块实现位于 src/regex/ 与 src/lib_c/升级时请结合目标平台确认 PCRE2 可用性。二、语言层lang新特性1.%W字符串数组字面量支持插值此前%w小写表示不插值的字符串数组字面量%W大写则是支持插值的对应形式。1.21.0 正式新增%W百分号字符串数组字面量[#16919]可直接在数组元素中嵌入#{}表达式name Crystal %W(hello #{name} world) # [hello, Crystal, world] # 也支持展开splat与拼接表达式 %W(a #{*[x, y]} b) # [a, x, y, b] %W(a b#{name}c) # [a, bCrystalc]仓库中的词法与格式化测试提供了大量可验证的行为样例spec/compiler/lexer/lexer_string_array_spec.cr 验证了%W(one two)的词法切分元素按空白分隔STRING_ARRAY_START→STRING→SPACE→STRING→STRING_ARRAY_ENDspec/compiler/formatter/formatter_spec.cr 验证了%W的格式化规则多余空白会被折叠为单个空格%W(one two three)→%W(one two three)且插值表达式会被正确识别与保留。同时 1.21.0 对符号/字符串数组字面量的解析做了格式化层面的标准化breaking[#16748]升级后建议用crystal tool format重新格式化旧代码以统一风格。2. 宏TypeNode#all_methods新增宏方法TypeNode#all_methods[#16902]返回包含类型祖先链上所有方法的定义列表。与仅返回类型自身方法的TypeNode#methods不同all_methods会沿type.ancestors逐层收集非常适合编写需要遍历完整方法面的宏代码如自动生成委托、校验接口实现等。其底层实现位于 src/compiler/crystal/macros/methods.crdef self.all_methods(type) defs [] of ASTNode collect_methods(defs, type) type.ancestors.each do |ancestor| collect_methods(defs, ancestor) end ArrayLiteral.new(defs) end宏侧入口在 src/compiler/crystal/macros.crTypeNode#all_methods两者结合即可确认all_methods先收集类型自身方法再遍历所有祖先类型补齐继承方法返回值是ArrayLiteral(Def)。3. 解析器与语义层增强ASTNode#inspect[#16699]为 AST 节点提供可读的检查输出方便调试与工具开发%var{}空表达式宏变量[#16772]宏变量支持空表达式形式如%var{}相关词法/解析修复见 [#16779]、[#16879]when Bar, Baz分支拆分[#17072]语义分析阶段将case的多值分支拆分为独立分支利于类型窄化与优化一系列解析器健壮性修复包括块参数赋值中的括号表达式[#16894]、赋值中(...)/[...]/{...}被静默忽略的问题[#16960]、self/nil/true/false后紧跟/、//的解析[#16942]等。三、标准库新特性与源码级解读1. 网络Socket#sendfile实验性1.21.0 为套接字新增experimental的Socket#sendfile[#16665]、[#17133]用于将文件内容高效地通过 socket 发送避免用户态拷贝。实现位于 src/socket.cr# File.open(audio.wav) do |file| # sock.sendfile(file, 44, file.info.size - 44) # file.pos # 0 # end # # The method leverages the sendfile (UNIX) and TransmitFile (Windows) # syscalls when available for the copy to happen entirely in the kernel. # The feature is emulated in user space on other targets. [Experimental] def sendfile(file : IO::FileDescriptor, offset : Int, count : Int) : Int64关键行为要点参数offset文件内起始偏移与count发送字节数两者均拒绝负值ArgumentError零拷贝UNIX 平台使用内核sendfile系统调用、Windows 使用TransmitFile其余平台在用户空间模拟不改变文件位置调用后file.pos保持原值加锁实现内部对目标文件与 socket 均加了fd_lock保证并发安全。配套地事件循环层新增Crystal::EventLoop::FileDescriptor#pread[#17068]与Crystal::EventLoop::Socket#sendfile并在 Kernel TLS 套接字上禁用了传输层预读[#17053]以配合零拷贝路径。2. 网络HTTP::WebSocket#receive同步接收新增HTTP::WebSocket#receive[#16689]作为同步调用方式允许在无需显式事件循环回调的情况下逐条读取 WebSocket 消息简化需要线性读写的协议处理代码。3. 文本String#present?新增String#present?[#16930]与既有的#blank?形成互补。实现位于 src/string.cr# Returns true if this string is not #blank?. def present? : Bool !blank? endblank?的定义同文件 L3033-L3038将“空串或仅含 Unicode 空白字符”视为 blank因此.present? # false .present? # false a .present? # true hello.present? # trueEnumerable#present?也同步存在src/enumerable.cr可统一用于参数校验与表单输入判断。4. 系统Path#kind与进程 API 增强Path#kind[#16917]暴露路径类型判断能力Processsplat 重载[#16975]Process.capture、.run、.new新增 splat 参数重载传参更灵活Process::Status.[][#17003]新增构造器同时隐藏了平台特定的Process::Status构造器[#16997]deprecation统一跨平台创建状态对象的方式。5. 序列化JSON::Field嵌套root与 URI 参数忽略控制JSON::Field支持嵌套root属性[#17016]允许在嵌套对象字段上声明root配合序列化注解实现更灵活的 JSON 结构映射URI::Params::Field(ignore:)[#17029]新增ignore_serialize/ignore_deserialize开关可在序列化/反序列化时选择性跳过字段。JSON::Field中的同类开关ignore、ignore_serialize、ignore_deserialize在 src/json/serialization.cr 有完整文档ignore_serialize的值可以是任意 Crystal 表达式并在运行时求值例如按条件跳过字段[JSON::Field(ignore_serialize: -(v : String) { v.empty? })] property token : String?相关宏逻辑位于 src/json/serialization.crignore_serialize为 truthy 时跳过序列化、ignore_deserialize为 true 时跳过反序列化。6. 文本UUID.v6与UUID.v8生成器1.21.0 为UUID补充了 RFC 9562 的 v6 与 v8 生成器[#17010]实现位于 src/uuid.cr。UUID.v6L343-L370v6 是 v1 的字段兼容版本将时间戳按“最高位在前”重排使 UUID 可按创建时间字典序排序UUID.v6 # 可选参数clock_seq单调递增序列号仅用 14 位、node_idMAC 地址 UUID.v6(clock_seq: 1234_u16, node_id: MAC.new(...))实现细节now采用 100ns 粒度的 60 位时间戳Time.local.to_unix_ns / 100 122192928000000000clock_seq未指定时取当前毫秒亚秒值并置 variant 位node_id未指定时用Random::Secure生成随机节点 ID 并置组播位。UUID.v8L396-L426面向实验性/厂商自定义场景由调用方定义全部 128 位语义仅强制覆写6 位字节 6 的高半字节置为0x8版本 8、字节 8 的高两位置为0b10RFC 9562 variant其余 122 位原样保留require uuid buf StaticArray(UInt8, 16).new(0_u8) IO::ByteFormat::BigEndian.encode(shard_id, buf.to_slice[0, 2]) IO::ByteFormat::BigEndian.encode(seq, buf.to_slice[2, 4]) # bytes 6 and 8 will have 6 bits overwritten; leave them as padding uuid UUID.v8(buf)注意设计自定义布局时避免在字节 6 高半字节与字节 8 高两位放置有效数据这两处会被无条件覆写。7. 加密OpenSSL 4.0 支持支持 OpenSSL 4.0[#16839]标准库全面适配 OpenSSL 4.0 API 变更Windows MSVC 下支持 OpenSSL 4.x DLL[#17116]补齐 Windows 平台的动态库加载。相关绑定与适配位于 src/openssl/ 与 src/lib_c/ 对应平台目录。8. 规范测试#should/#should_not链式调用1.21.0 允许链式编写#should、#should_not断言[#17020]例如result.should be_a(Int32).should_not eq(0)使断言更紧凑spec 代码可读性提升。9. CLIOptionParser 对齐与without_main标志长选项在 OptionParser 帮助输出中对齐显示[#16914]并修复摘要换行条件[#16915]新增without_main编译标志[#17074]适合构建无需main入口的嵌入/链接场景。四、编译器与工具链更新1. 调试器debugger1.21.0 对调试体验做了一轮集中改进[#16830]、[#16831]、[#16832]改进 proc 调试元数据为常量与类变量生成调试元数据改进 LLDB 集合类型格式化器对应 etc/lldb/crystal_formatters.py。2. 解析器与语义分析when Bar, Baz分支拆分[#17072]语义层将case多值分支拆分为独立分支改善类型推断泛型类型common_descendent对称化[#16999]修复两个泛型类的公共子类计算对应 issue #10831distinct lib 类型别名不再被误判为同一类型[#16961]out声明变量的类型冻结修复[#16870]、lookup_matches_in_type拒绝部分匹配[#16867]、宏定义初始化器中未初始化祖先实例变量的检测[#16959]等一批语义修复。3. 代码生成-Os/-Oz优化模式为-Os与-Oz设置optsize、minsize函数属性[#16983]体积优先的编译模式得到更精准的 LLVM 提示未知调试位置使用 line 0[#17013]修复调试行号缺失时的行为。4. REPL 与解释器修复 REPL 输入类时自动缩进问题[#16910]修复解释器 multidispatch 缓存冲突[#16958]新增解释器upcast_distinct支持Pointer到Pointer的向上转型[#16962]。5. 格式化器formatter1.21.0 修复了多个格式化边界问题空then后跟尾随注释[#16878]三元if中尾随注释的空白[#16880]空字符串字面量续行[#16817]splat 参数的注解格式化[#16987]heredoc 中空行被剥离的问题[#17034]符号/字符串数组字面量解析标准化breaking[#16748]。五、Chores、性能与基础设施1. 弃用Deprecations清单升级前请重点排查以下 API模块弃用项PRcliColorize.on_tty_only![#16859]concurrencyspawn(same_thread:)[#17097]filesIO::Memory.new参数重命名为writable[#16858]、[#16883]system平台特定Process::Status构造器隐藏[#16997]2. 性能优化Hash.zip预分配[#17054]按正确大小预分配哈希容量避免 zip 过程中反复扩容大量键值对场景下有可感知提升。3. 关键重构Refactor编译器 CLI 错误处理拆分并以CompilerError取代abort[#16984]、[#16995]Dir::Globber重构为带实例方法的 struct[#16899]ELF / Mach-O / PE 与 DWARF 段改为 mmap 而非解析[#16939]、[#17134]显著降低进程启动时的解析开销libevent 事件循环线程安全修复[#17031]移除废弃的IO::Evented与Crystal::ThreadLocalValue[#17032]Win32 IOCP 事件循环重构[#17101]overlapped_connect/overlapped_accept合并进EventLoop::IOCP[#17090]OpenBSD 事件循环默认切换为 kqueue[#17123]并支持EVFILT_USER[#17121]。4. 构建与 CIMakefile将install目标拆分为子组件并为install构建 manpages[#16980]、[#16991]产物对应 doc/man/ 中的手册提取CRYSTAL_BOOTSTRAP_VERSION到bin/ci[#16966]用rumdl取代markdownlint[#17069]、[#17078]对应配置文件 rumdl.toml新增compiler-cli 测试套件[#17033]覆盖 spec/compiler-cli/ 下的 CLI 行为。六、升级路径与验证建议先扫弃用项全局搜索on_tty_only!、spawn(same_thread:、IO::Memory.new的旧参数名按上表迁移确认 PCRE2 环境正则重度用户需确保部署与 CI 环境提供 PCRE2避免 1.21.0 关闭旧 PCRE 回退后出现运行时错误重新格式化数组字面量解析已标准化[#16748]运行crystal tool format统一代码风格验证并发代码Execution Contexts 正式发布后关注Fiber::ExecutionContext相关 API 的稳定性变化并逐步迁移spawn(same_thread:)用法按模块回归网络WebSocket/HTTP Client/SSL、序列化JSON/URI::Params、UUID 是本次变更最密集的模块可参照 spec/std/ 与 spec/compiler/ 中的新增测试用例进行回归。参考完整变更日志doc/changelogs/v1.21.md历史版本日志doc/changelogs/README.md核心实现String#present?src/string.cr、UUID.v6/v8src/uuid.cr、Socket#sendfilesrc/socket.cr、TypeNode#all_methodssrc/compiler/crystal/macros/methods.cr测试证据%W词法spec/compiler/lexer/lexer_string_array_spec.cr、%W格式化spec/compiler/formatter/formatter_spec.cr说明以上 PR 编号如 [#17100]均引用自 doc/changelogs/v1.21.md 原文便于你在对应提交历史中定位具体改动。【免费下载链接】crystalThe Crystal Programming Language项目地址: https://gitcode.com/gh_mirrors/cr/crystal创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门