trait 类似接口,定义了一组方法,struct可以实现trait
std trait
struct Point {x: i32,y: i32,}impl Add for Point {type Output = Self;fn add(self, rhs: Self) -> Self::Output {Point{x: self.x + rhs.x,y: self.y + rhs.y,}}}#[test]fn add_point() {let p1 = Point {x: 1,y: 2,};let p2 = Point {x: 1,y: 2,};let p3 = p1 + p2;assert_eq!(p3.x, 2);assert_eq!(p3.y, 4);}
fn write_to_buf(out: &mut Write) -> std::io::Result<()> {out.write_all(b"hello world")?;out.flush()}#[test]fn test_say_hello() {let mut bytes: Vec<u8> = vec![];let res = write_to_buf(&mut bytes);assert_eq!(res.is_ok(), true);assert_eq!(bytes, b"hello world");}
custom trait
trait NoisyAnimal {fn make_noise(&self) -> &'static str;}struct Cat{}struct Dog{}impl NoisyAnimal for Cat {fn make_noise(&self) -> &'static str {"hello"}}impl NoisyAnimal for Dog {fn make_noise(&self) -> &'static str {"bark"}}fn main() {let cat = Cat{};println!("{}", cat.make_noise());let dog = Dog{};println!("{}", dog.make_noise());}
use trait as parameter
fn make_noises(n: &impl NoisyAnimal) -> &'static str {n.make_noise()}fn make_noises2<T>(n: &T) -> &'static strwhere T: NoisyAnimal{n.make_noise()}fn main() {let cat = Cat{};let dog = Dog{};println!("{}", make_noises(&dog));println!("{}", make_noises2(&cat));}
trait has no Size
fn main() {let cat = Cat{};println!("{}", cat.make_noise());let dog = Dog{};println!("{}", dog.make_noise());println!("{}", make_noises(&dog));println!("{}", make_noises2(&cat));let animals: Vec<Box<dyn NoisyAnimal>> = vec![Box::new(cat), Box::new(dog)];for a in animals.iter() {println!("{}", a.make_noise());}// 注意,这里cat,dog已经被move了,所以如果再次引用就会编译报错了}
