Rust-reference/items/generics

来自菜鸟教程
跳转至:导航、​搜索

Type and Lifetime Parameters

类型参数和生存期参数

generics.md

commit: f8e76ee9368f498f7f044c719de68c7d95da9972
本章译文最后维护日期:2020-11-9

句法

Generics :
   < GenericParams >

GenericParams :
      LifetimeParams
   | ( LifetimeParam , )* TypeParams

LifetimeParams :
   ( 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
   | TypeBoundWhereClauseItem

LifetimeWhereClauseItem :
   Lifetime : LifetimeBounds

TypeBoundWhereClauseItem :
   ForLifetimes? Type : TypeParamBounds?

ForLifetimes :
   for < LifetimeParams >

where子句提供了另一种方法来为类型参数和生存期参数指定约束(bound),甚至可以为非类型参数的类型指定约束。

当定义程序项时,where子句提供的约束与该程序项的各种参数(包括生存期和高阶生存期)无关也是可以通过安全检查的。但这样做会带来潜在的错误。

对某些泛型类型来说,在定义它的 where子句时,CopyCloneSized 这些约束也可以通过安全检查。但将 CopyClone 作为可变引用、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
}