Bounds

Just like generic types can be bounded, lifetimes (themselves generic) use bounds as well. The : character has a slightly different meaning here, but + is the same. Note how the following read:

  1. T: 'a: All references in T must outlive lifetime 'a.
  2. T: Trait + 'a: Type T must implement trait Trait and all references in T must outlive 'a.

The example below shows the above syntax in action:

1. use std::fmt::Debug; // Trait to bound with.

3. #[derive(Debug)]
4. struct Ref<'a, T: 'a>(&'a T);
5. // `Ref` contains a reference to a generic type `T` that has
6. // an unknown lifetime `'a`. `T` is bounded such that any
7. // *references* in `T` must outlive `'a`. Additionally, the lifetime
8. // of `Ref` may not exceed `'a`.

10. // A generic function which prints using the `Debug` trait.
11. fn print<T>(t: T) where
12. T: Debug {
13. println!("`print`: t is {:?}", t);
14. }

16. // Here a reference to `T` is taken where `T` implements
17. // `Debug` and all *references* in `T` outlive `'a`. In
18. // addition, `'a` must outlive the function.
19. fn print_ref<'a, T>(t: &'a T) where
20. T: Debug + 'a {
21. println!("`print_ref`: t is {:?}", t);
22. }

24. fn main() {
25. let x = 7;
26. let ref_x = Ref(&x);

28. print_ref(&ref_x);
29. print(ref_x);
30. }

See also:

generics, bounds in generics, and multiple bounds in generics