消除重叠 trait

一个类型可以实现许多不同的 trait。如果两个 trait 都需要相同的名称怎么办?例如,许多 trait 可能拥有名为 get() 的方法。他们甚至可能有不同的返回类型!

有个好消息:由于每个 trait 实现都有自己的 impl 块,因此很清楚您要实现哪个 trait 的 get 方法。

何时需要调用这些方法呢?为了消除它们之间的歧义,我们必须使用完全限定语法(Fully Qualified Syntax)。

  1. trait UsernameWidget {
  2. // 从这个 widget 中获取选定的用户名
  3. fn get(&self) -> String;
  4. }
  5. trait AgeWidget {
  6. // 从这个 widget 中获取选定的年龄
  7. fn get(&self) -> u8;
  8. }
  9. // 同时具有 UsernameWidget 和 AgeWidget 的表单
  10. struct Form {
  11. username: String,
  12. age: u8,
  13. }
  14. impl UsernameWidget for Form {
  15. fn get(&self) -> String {
  16. self.username.clone()
  17. }
  18. }
  19. impl AgeWidget for Form {
  20. fn get(&self) -> u8 {
  21. self.age
  22. }
  23. }
  24. fn main() {
  25. let form = Form{
  26. username: "rustacean".to_owned(),
  27. age: 28,
  28. };
  29. // 如果取消注释此行,则会收到一条错误消息,提示 “multiple `get` found”(找到了多个`get`)。
  30. // 因为毕竟有多个名为 `get` 的方法。
  31. // println!("{}", form.get());
  32. let username = <Form as UsernameWidget>::get(&form);
  33. assert_eq!("rustacean".to_owned(), username);
  34. let age = <Form as AgeWidget>::get(&form);
  35. assert_eq!(28, age);
  36. }

参见:

《Rust 程序设计语言》中关于“完全限定语法”的章节