内容提要
Rust 的 Const Generics 项目组推出“Generic Const Arguments”(GCA)系列特性,取代旧的 generic_const_exprs。GCA 允许在常量泛型中使用泛型参数表达式,如结构体、数组、元组及常量项,需写在 gca! 宏内。目前包含 gca_adts、gca_const_items、gca_min_const_items 等特性,尚未稳定,团队正征集反馈。
延伸解读
GCA 与旧特性的关系
GCA 旨在取代自 2021 年 min_const_generics 稳定以来就存在的 generic_const_exprs 特性。尽管 GCA 使 generic_const_exprs 变得过时,但项目组认为投入时间研究它是非常有价值的,因为 GCA 的设计和实现很大程度上受到了 generic_const_exprs 的启发。
当前稳定版的限制
在稳定版 Rust 中,常量泛型仅支持泛型参数本身(如 { N })或完全具体的常量(如 { 1 + 1 })。无法使用像 [u8; T::NUM_BYTES] 或 [u8; N + 1] 这样的数组长度,这限制了许多有用的抽象,并迫使用户依赖 typenum crate。
gca! 宏的语义差异
GCA 特性要求新支持的表达式必须写在 gca! 宏调用内。与普通常量参数相比,gca!(..) 常量参数允许使用泛型参数,但支持的表达式种类更少,例如目前不支持算术运算或函数调用。gca!(1 + 1) 或 gca!(foo()) 会报错,而 { 1 + 1 } 或 { foo() } 则不会。
gca_min_const_items 的取舍
gca_min_const_items 是 gca_const_items 的最小版本,仅支持定义为 gca!(..) 表达式的常量项,且不需要 -Znext-solver 标志。它通过限制表达性来避免 post-mono 错误和令人困惑的错误信息,并且更容易实现,因此有望比完整版更早达到稳定质量。
Q&A
Rust 的 Generic Const Arguments (GCA) 是什么?它和之前的 generic_const_exprs 有什么关系?
GCA 是 Const Generics 项目组推出的一系列特性,旨在支持在常量泛型中使用更复杂的泛型参数表达式。它被设计用来取代自 2021 年 min_const_generics 稳定以来就存在的 generic_const_exprs 特性。GCA 的设计和实现很大程度上受到了 generic_const_exprs 的启发。
在 Rust 稳定版中,常量泛型目前支持哪些表达式?有什么限制?
在稳定版中,常量泛型仅支持泛型参数本身(如 { N })或完全具体的常量(如 { 1 + 1 })。无法使用像 [u8; T::NUM_BYTES] 或 [u8; N + 1] 这样的数组长度表达式,这限制了许多有用的抽象,迫使用户依赖 typenum crate。
GCA 的 gca_adts 特性支持哪些类型的表达式?能举几个例子吗?
gca_adts 特性支持在常量泛型中使用结构体、枚举、数组和元组表达式,这些表达式可以包含泛型参数。例如:gca!(Foo { field: N })、gca!(TupleStruct(N))、gca!(MyEnum::Record { x: N })、gca!([N1, 12])、gca!((N1, 12))。目前不支持数组重复表达式(如 gca!([N1; 2])),但计划未来支持。
gca_const_items 和 gca_min_const_items 有什么区别?
gca_const_items 支持在类型系统中使用任意常量项,需要启用 -Znext-solver 不稳定标志,并可能引入 post-mono 错误和令人困惑的错误信息。gca_min_const_items 是它的最小版本,仅支持定义为 gca!(..) 表达式的常量项,不需要 -Znext-solver,且规则更简单、更易实现,有望更早稳定。
为什么 GCA 要求把新表达式写在 gca! 宏里?未来会取消这个要求吗?
目前所有 GCA 特性都要求将新支持的表达式写在 gca! 宏调用内,因为这样编译器可以明确区分哪些常量参数允许使用泛型参数。团队意识到这带来了显著的易用性问题,正在研究如何避免显式宏,但尚未找到好的解决方案。已有实验性的 gca_macroless_args 和 gca_macroless_items 特性尝试隐式添加宏,但效果不佳,目前仍推荐显式使用 gca!(..)。
GCA 特性目前稳定了吗?如何提供反馈?
GCA 系列特性目前尚未稳定,团队认为还需要一段时间才能达到可以提出 RFC 的完善程度。他们非常希望听到用户在使用中遇到的问题,包括编译器崩溃、设计问题或使用困难。反馈渠道是 project-const-generics 的 GitHub 仓库提交 issue,或在 project-const-generics 的 Zulip 频道发起讨论。