trait 类似接口,定义了一组方法,struct可以实现trait

std trait

  1. struct Point {
  2. x: i32,
  3. y: i32,
  4. }
  5. impl Add for Point {
  6. type Output = Self;
  7. fn add(self, rhs: Self) -> Self::Output {
  8. Point{
  9. x: self.x + rhs.x,
  10. y: self.y + rhs.y,
  11. }
  12. }
  13. }
  14. #[test]
  15. fn add_point() {
  16. let p1 = Point {
  17. x: 1,
  18. y: 2,
  19. };
  20. let p2 = Point {
  21. x: 1,
  22. y: 2,
  23. };
  24. let p3 = p1 + p2;
  25. assert_eq!(p3.x, 2);
  26. assert_eq!(p3.y, 4);
  27. }
  1. fn write_to_buf(out: &mut Write) -> std::io::Result<()> {
  2. out.write_all(b"hello world")?;
  3. out.flush()
  4. }
  5. #[test]
  6. fn test_say_hello() {
  7. let mut bytes: Vec<u8> = vec![];
  8. let res = write_to_buf(&mut bytes);
  9. assert_eq!(res.is_ok(), true);
  10. assert_eq!(bytes, b"hello world");
  11. }

custom trait

  1. trait NoisyAnimal {
  2. fn make_noise(&self) -> &'static str;
  3. }
  4. struct Cat{}
  5. struct Dog{}
  6. impl NoisyAnimal for Cat {
  7. fn make_noise(&self) -> &'static str {
  8. "hello"
  9. }
  10. }
  11. impl NoisyAnimal for Dog {
  12. fn make_noise(&self) -> &'static str {
  13. "bark"
  14. }
  15. }
  16. fn main() {
  17. let cat = Cat{};
  18. println!("{}", cat.make_noise());
  19. let dog = Dog{};
  20. println!("{}", dog.make_noise());
  21. }

use trait as parameter

  1. fn make_noises(n: &impl NoisyAnimal) -> &'static str {
  2. n.make_noise()
  3. }
  4. fn make_noises2<T>(n: &T) -> &'static str
  5. where T: NoisyAnimal
  6. {
  7. n.make_noise()
  8. }
  9. fn main() {
  10. let cat = Cat{};
  11. let dog = Dog{};
  12. println!("{}", make_noises(&dog));
  13. println!("{}", make_noises2(&cat));
  14. }

trait has no Size

  1. fn main() {
  2. let cat = Cat{};
  3. println!("{}", cat.make_noise());
  4. let dog = Dog{};
  5. println!("{}", dog.make_noise());
  6. println!("{}", make_noises(&dog));
  7. println!("{}", make_noises2(&cat));
  8. let animals: Vec<Box<dyn NoisyAnimal>> = vec![Box::new(cat), Box::new(dog)];
  9. for a in animals.iter() {
  10. println!("{}", a.make_noise());
  11. }
  12. // 注意,这里cat,dog已经被move了,所以如果再次引用就会编译报错了
  13. }