泛型

Traits can also be generic, just like types and functions. A trait’s parameters get concrete types when it is used.

  1. #[derive(Debug)]
  2. struct Foo(String);
  3. impl From<u32> for Foo {
  4. fn from(from: u32) -> Foo {
  5. Foo(format!("Converted from integer: {from}"))
  6. }
  7. }
  8. impl From<bool> for Foo {
  9. fn from(from: bool) -> Foo {
  10. Foo(format!("Converted from bool: {from}"))
  11. }
  12. }
  13. fn main() {
  14. let from_int = Foo::from(123);
  15. let from_bool = Foo::from(true);
  16. println!("{from_int:?}, {from_bool:?}");
  17. }
  • The From trait will be covered later in the course, but its definition in the std docs is simple.

  • Implementations of the trait do not need to cover all possible type parameters. Here, Foo::From("hello") would not compile because there is no From<&str> implementation for Foo.

  • Generic traits take types as “input”, while associated types are a kind of “output” type. A trait can have multiple implementations for different input types.

  • In fact, Rust requires that at most one implementation of a trait match for any type T. Unlike some other languages, Rust has no heuristic for choosing the “most specific” match. There is work on adding this support, called specialization.