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 str
where 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了,所以如果再次引用就会编译报错了
}