“where”关键字的语法和语义是什么



不幸的是,Rust关于where的文档非常缺乏。关键字仅出现在引用中的一个或两个不相关的示例中。

  1. where在以下代码中有什么语义差异?有什么不同吗?首选哪种形式?

    fn double_a<T>(a: T) -> T where T: std::num::Int {
        a + a
    }
    fn double_b<T: std::num::Int>(a: T) -> T {
        a + a
    }
    
  2. 在CharEq特性的实现中,似乎where被用作某种";选择器";为任何匹配某种闭包类型的对象实现Trait。我说得对吗?

有什么方法可以让我更好、更完整地了解where吗?(用法和语法的完整说明)

在您的示例中,这两个代码是严格等价的。

引入where子句是为了允许更具表现力的绑定检查,例如:

fn foo<T>(a: T) where Bar<T>: MyTrait { /* ... */ }

仅使用旧语法是不可能的。

使用where而不是原始语法通常是可读性的首选,即使旧语法仍然可以使用。

例如,你可以想象像这样的结构

fn foo<A, B, C>(a: A, b: B, c: C)
    where A: SomeTrait + OtherTrait,
          B: ThirdTrait<A>+ OtherTrait,
          C: LastTrait<A, B>
{
    /* stuff here */
}

即使仍然可以使用旧语法来表达,也可以通过这种方式更具可读性。

对于您关于CharEq特性的问题,代码为:

impl<F> CharEq for F where F: FnMut(char) -> bool {
    #[inline]
    fn matches(&mut self, c: char) -> bool { (*self)(c) }
    #[inline]
    fn only_ascii(&self) -> bool { false }
}

它的字面意思是:为已经实现特征FnMut(char) -> bool的所有类型F实现特征CharEq(也就是说,闭包或函数接受char并返回bool)。

有关更多详细信息,您可以查看引入where子句的RFC:https://github.com/rust-lang/rfcs/pull/135

最新更新