我有时会看到像 <T=Self>
这样的东西或 T=()
在通用结构/特征中。我怀疑这与泛型类型的默认类型有关 T
.但是我找不到任何文档。
我的问题是:
- 它的真正含义是什么?
- 有哪些可能的变体(可能像
<T=Self: 'static
> 这样疯狂的东西)? - 什么时候有用(示例)?
最佳答案
此语法可用于两种情况:默认类型参数和关联类型。要了解差异和使用,让我们看一下用于定义 +
运算符的 Add
特性:
pub trait Add<RHS = Self> {
type Output;
fn add(self, rhs: RHS) -> Self::Output;
}
默认类型参数
这里,类型参数RHS
有一个默认值:Self
。这意味着,每当我使用这个特征时,如果我省略它,这个类型参数的值将默认为 Self
。例如:
impl Add for Foo { /* ... */ }
与
相同impl Add<Foo> for Foo { /* ... */ }
同样,
fn foo<T>(t: T) where T: Add { /* ... */ }
与
相同fn foo<T>(t: T) where T: Add<T> { /* ... */ }
关联类型
特征 Add
也有一个关联类型:Output
。此类型由特征的实现选择。
这背后的原因是当输入类型相同时用不同的输出类型实现 Add
没有任何意义:一次 Self
和 RHS
已知,Output
类型无法选择。
此构造也用于迭代器,例如,当您迭代容器时,您无法选择迭代器生成的值的类型:因此它是关联类型。
通过使用 Foo = Bar
语法,可以在 where
子句中为关联类型选择一个值。例如:
fn foo<I>(i: I) where I: Iterator<Item=u8> { /* ... */ }
此函数可以在任何产生 u8
值的迭代器上工作。
总结
泛型构造定义中使用的语法 Foo=Bar
允许您为类型参数设置默认值,并用于 where
子句中它允许您匹配关联类型的值。
没有可能的变体,例如 Foo = Bar : Baz
或类似的东西。
关于generics - 此语法是什么意思 (<T=Self>) 以及何时使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32036288/