今天我在这里遇到了一个有点奇怪的语法 - where ()
:
https ://github.com/binator/self/tree/80ba2ade?tab=readme-ov-file#example
fn hex_primary<Stream, Context>(stream: Stream) -> Parsed<u8, Stream, Context>
where
(): IntRadixParse<Stream, Context, u8>,
{
uint_radix(2, Radix::HEX).parse(stream)
}
在我看来,它看起来像是“绑定在单元类型(又名空元组)上”,但我无法理解。单元类型默认不会实现所有特征,对吗?不幸的是,官方文档太模糊,不够完整(同时过于冗长),我在其中找不到任何相关内容。
原始 RFC 的 forwhere
子句也提到了这种语法,但没有适当的解释:
https://rust-lang.github.io/rfcs/0135-where.html#alternatives
fn increment<T>(c: T) -> T
where () : Add<int,T,T>
{
1 + c
}
但除此之外,我知道不仅可以在特征泛型中指定此类界限。
那么它是什么,何时使用,为什么需要它以及它解决了哪些问题?
在代码片段中,
where
子句用于缩小通用约束。不是定义所有约束,(): IntRadixParse<Stream, Context, u8>
而是使用,这意味着无论类型Stream
和Context
类型是什么,它们都必须遵循的约束IntRadixParse
。特征
IntRadixParse
是注意:它使用特征别名不稳定功能
因此,要编写没有奇怪的单位约束语法的函数,它将是这样的
注意:函数中
Token
被替换为u8
另一个例子:
(): IntRadixParse<Stream, Context, u8>
确实是对单位类型的限制。它之所以有效,是因为特征别名1定义如下:请特别注意之前缺失的特征
where
,没有特征,因此在条件成立的情况下,这是没有任何特征的别名。每种类型都满足“实现一组空的特征”,因此编译器唯一需要证明的就是边界。简而言之,因为
Self
没有被引用,也没有特征需要它满足,所以()
你可以在那里写任何类型而不是 unit。当类型无关紧要时,Rust 程序员经常使用 unit。这使得特征别名对于缩写一堆界限很有用,如Timsib Adnap 的答案中解释的那样