这个语法是什么意思(<T = Self>)以及何时使用它?

Chr*_*oph 5 generics rust

我有时看东西好像<T=Self>还是T=()在普通的结构/特性.我怀疑这与泛型类型的默认类型有关T.我找不到任何文件.

我的问题是:

  • 它到底意味着什么?
  • 可能有哪些变化(也许是疯狂的事情<T=Self: 'static)?
  • 什么时候有用(例子)?

Lev*_*ans 6

此语法可用于两种情况:默认类型参数和关联类型.要查看差异和使用,让我们看看Add用于定义+运算符的特征:

pub trait Add<RHS = Self> {
    type Output;
    fn add(self, rhs: RHS) -> Self::Output;
}
Run Code Online (Sandbox Code Playgroud)

默认类型参数

这里,type参数RHS有一个默认值:Self.这意味着,每当我使用此特征时,Self如果我省略它,则此类型参数的值将默认为.例如:

impl Add for Foo { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

是相同的

impl Add<Foo> for Foo { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

同样,

fn foo<T>(t: T) where T: Add { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

是相同的

fn foo<T>(t: T) where T: Add<T> { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

相关类型

特征Add也有一个相关的类型:Output.这种类型是通过特征的实现来选择的.

这背后的原因是,它不会作出任何意义,实现Add不同的输出类型,同时输入的类型是相同的:一旦SelfRHS已知,Output类型不能选择.

此构造也用于迭代器,例如,当您遍历容器时,您无法选择迭代器生成的值的类型:因此它是关联类型.

where通过使用此Foo = Bar语法,可以在子句中为关联类型选择值.例如:

fn foo<I>(i: I) where I: Iterator<Item=u8> { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

此函数可以处理任何产生u8值的迭代器.

总结一下

Foo=Bar泛型构造定义中使用的语法允许您为类型参数设置默认值,并在where子句中使用它允许您匹配关联类型的值.

没有可能的变化Foo = Bar : Baz或类似的东西.