Type and Lifetime Parameters
类型参数和生存期参数
commit: f8e76ee9368f498f7f044c719de68c7d95da9972
本章译文最后维护日期:2020-11-9
句法
Generics :
<GenericParams>GenericParams :
LifetimeParams
| ( LifetimeParam,)* TypeParamsLifetimeParams :
( LifetimeParam,)* LifetimeParam?LifetimeParam :
OuterAttribute? LIFETIME_OR_LABEL (:LifetimeBounds )?TypeParams:
( TypeParam,)* TypeParam?TypeParam :
OuterAttribute? IDENTIFIER (:TypeParamBounds? )? (=Type )?
函数、类型别名、结构体、枚举、联合体、trait 和实现可以通过类型参数和生存期参数达到参数化配置的的效果。这些参数在尖括号(<…>)中列出,通常都是紧跟在程序项名称之后和程序项的定义之前。对于实现,因为它没有名称,那它们就直接位于关键字 impl 之后。生存期参数必须在类型参数之前声明。下面给出一些带类型参数和生存期参数的程序项的示例:
fn foo<'a, T>() {}
trait A<U> {}
struct Ref<'a, T> where T: 'a { r: &'a T }
引用、裸指针、数组、切片、元组和函数指针也有生存期参数或类型参数,但这些程序项不能使用路径句法去引用。
Where clauses
where子句
句法
WhereClause :
where( WhereClauseItem,)* WhereClauseItem ?WhereClauseItem :
LifetimeWhereClauseItem
| TypeBoundWhereClauseItemLifetimeWhereClauseItem :
Lifetime:LifetimeBoundsTypeBoundWhereClauseItem :
ForLifetimes? Type:TypeParamBounds?ForLifetimes :
for<LifetimeParams>
where子句提供了另一种方法来为类型参数和生存期参数指定约束(bound),甚至可以为非类型参数的类型指定约束。
当定义程序项时,where子句提供的约束与该程序项的各种参数(包括生存期和高阶生存期)无关也是可以通过安全检查的。但这样做会带来潜在的错误。
对某些泛型类型来说,在定义它的 where子句时,Copy、Clone 和 Sized 这些约束也可以通过安全检查。但将 Copy 或 Clone 作为可变引用、trait对象或切片的约束上错误的,将 Sized 作为 trait对象或切片的约束也是错误的。
struct A<T>
where
T: Iterator, // 可以用 A<T: Iterator> 来替代
T::Item: Copy,
String: PartialEq<T>,
i32: Default, // 允许,但没什么用
i32: Iterator, // 错误: 此 trait约束不适合,i32 没有实现 Iterator
[T]: Copy, // 错误: 此 trait约束不适合,切片上不能有此 trait约束
{
f: T,
}
Attributes
属性
泛型生存期参数和泛型类型参数允许属性,但在目前这个位置还没有任何任何有意义的内置属性,但用户可能可以通过自定义的派生属性来设置一些有意义的属性。
下面示例演示如何使用自定义派生属性修改泛型参数的含义。
// 假设 MyFlexibleClone 的派生项将 `my_flexible_clone` 声明为它可以理解的属性。
#[derive(MyFlexibleClone)]
struct Foo<#[my_flexible_clone(unbounded)] H> {
a: *const H
}