这个语法可以用于两种情况:默认类型参数和关联类型。为了看到差异和使用方法,让我们来看一下 Add
特性,用于定义 +
操作符:
pub trait Add<RHS = Self> {
type Output;
fn add(self, rhs: RHS) -> Self::Output;
}
默认类型参数
在这里,类型参数 RHS
有一个默认值: Self
。这意味着,每当我使用此 trait 时,如果省略该参数,则该类型参数的值将默认为 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
这样的变化或类似的事情。