rust学习
今天的rust的学习主要是学了trait,我原本对trait的印象就是一个放在#[derive()]里面的,比如增加了Display或者Debug的trait之后,就可以直接在println里面打印结构体。
我今天主要学的就是重载运算符、Drop和trait的特性。简单总结一下
trait
trait是什么,顾名思义,trait的中文是特征,即一种定义共享行为的机制,不管是什么数据类型,只要定义了这个trait,就一定要完成某个共享行为。比如说:Display、Debug、Drop…..对于绝大多数数据类型,这些trait都是满足的。 为什么要有trait?我自己总结下来有三点原因:
代码复用:
对于任何数据类型,他的同一个trait都可以有自己的实现方法,但是如果该数据类型没有自定义实现方法,可以通过trait得到一个默认的方法。
trait Greet {
fn name(&self) -> String;
fn greet(&self) -> String { // 默认实现
format!("Hello, {}!", self.name())
}
}泛型约束:
让函数接受“任何实现了某 trait 的类型“,实现静态多态。
fn make_sound<T: Animal>(animal: &T) {
println!("{} says {}", animal.name(), animal.speak());
}
// 或用 impl Trait 语法(更简洁)
fn make_sound(animal: &impl Animal) { ... }编译器在编译之后就单态化他了。
动态分发:
使用dyn trait实现运行时的多态,可以在box里面存放不同的类型。
let animals: Vec<Box<dyn Animal>> = vec![
Box::new(Dog),
Box::new(Cat),
];
for a in &animals {
println!("{}", a.speak()); // 运行时决定调用哪个实现
}dyn
具体说一下trait的动态分发的例子:
fn main() {
let rn = 0.63;
println!("{}", random_animal(rn).noise());
println!("helloworld")
}
struct Sheep {}
struct Cow {}
trait Animal {
fn noise(&self) -> &'static str;
}
impl Animal for Sheep {
fn noise(&self) -> &'static str {
"mie ~~~"
}
}
impl Animal for Cow {
fn noise(&self) -> &'static str {
"mou ~~~"
}
}
fn random_animal(rn: f64) -> Box<dyn Animal> {
if rn > 0.5 {
Box::new(Sheep {})
} else {
Box::new(Cow {})
}
}上面代码中,对于random_animal的返回,就使用了动态分发,不需要提前预设好类型,不需要指定是Sheep还是Cow。
评论
注册或登录后即可评论。