Syntax
Generics :
<
GenericParams>
GenericParams :
LifetimeParams
| ( LifetimeParam,
)* TypeParamsLifetimeParams :
( LifetimeParam,
)* LifetimeParam?LifetimeParam :
OuterAttribute? LIFETIME_OR_LABEL (:
LifetimeBounds )?TypeParams:
( TypeParam,
)* TypeParam?TypeParam :
OuterAttribute? IDENTIFIER (:
TypeParamBounds? )? (=
Type )?
Functions, type aliases, structs, enumerations, unions, traits, and implementations may be parameterized by types and lifetimes. These parameters are listed in angle brackets (<...>
), usually immediately after the name of the item and before its definition. For implementations, which don't have a name, they come directly after impl
. Lifetime parameters must be declared before type parameters. Some examples of items with type and lifetime parameters:
#![allow(unused)] fn main() { fn foo<'a, T>() {} trait A<U> {} struct Ref<'a, T> where T: 'a { r: &'a T } }
References, raw pointers, arrays, slices, tuples, and function pointers have lifetime or type parameters as well, but are not referred to with path syntax.
Syntax
WhereClause :
where
( WhereClauseItem,
)* WhereClauseItem ?WhereClauseItem :
LifetimeWhereClauseItem
| TypeBoundWhereClauseItemLifetimeWhereClauseItem :
Lifetime:
LifetimeBoundsTypeBoundWhereClauseItem :
ForLifetimes? Type:
TypeParamBounds?ForLifetimes :
for
<
LifetimeParams>
Where clauses provide another way to specify bounds on type and lifetime parameters as well as a way to specify bounds on types that aren't type parameters.
Bounds that don't use the item's parameters or higher-ranked lifetimes are checked when the item is defined. It is an error for such a bound to be false.
Copy
, Clone
, and Sized
bounds are also checked for certain generic types when defining the item. It is an error to have Copy
or Clone
as a bound on a mutable reference, trait object or slice or Sized
as a bound on a trait object or slice.
#![allow(unused)] fn main() { struct A<T> where T: Iterator, // Could use A<T: Iterator> instead T::Item: Copy, String: PartialEq<T>, i32: Default, // Allowed, but not useful i32: Iterator, // Error: the trait bound is not satisfied [T]: Copy, // Error: the trait bound is not satisfied { f: T, } }
Generic lifetime and type parameters allow attributes on them. There are no built-in attributes that do anything in this position, although custom derive attributes may give meaning to it.
This example shows using a custom derive attribute to modify the meaning of a generic parameter.
// Assume that the derive for MyFlexibleClone declared `my_flexible_clone` as // an attribute it understands. #[derive(MyFlexibleClone)] struct Foo<#[my_flexible_clone(unbounded)] H> { a: *const H }
© 2010 The Rust Project Developers
Licensed under the Apache License, Version 2.0 or the MIT license, at your option.
https://doc.rust-lang.org/reference/items/generics.html