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.
  2. #[derive(Debug)]
  3. struct Ref<'a, T: 'a>(&'a T);
  4. // `Ref` contains a reference to a generic type `T` that has
  5. // an unknown lifetime `'a`. `T` is bounded such that any
  6. // *references* in `T` must outlive `'a`. Additionally, the lifetime
  7. // of `Ref` may not exceed `'a`.
  8. // A generic function which prints using the `Debug` trait.
  9. fn print<T>(t: T) where
  10. T: Debug {
  11. println!("`print`: t is {:?}", t);
  12. }
  13. // Here a reference to `T` is taken where `T` implements
  14. // `Debug` and all *references* in `T` outlive `'a`. In
  15. // addition, `'a` must outlive the function.
  16. fn print_ref<'a, T>(t: &'a T) where
  17. T: Debug + 'a {
  18. println!("`print_ref`: t is {:?}", t);
  19. }
  20. fn main() {
  21. let x = 7;
  22. let ref_x = Ref(&x);
  23. print_ref(&ref_x);
  24. print(ref_x);
  25. }

See also:

generics, bounds in generics, and
multiple bounds in generics