Rust的trait特征
AI摘要: 本文详细介绍了Rust语言中的trait特性,包括其基本用法、继承与多继承操作、静态分发和动态分发机制。通过示例代码展示了如何定义和实现trait,以及使用Send和Sync约束实现者的能力。文章还对比了trait与接口的不同之处,解释了静态分发(编译时确定类型并生成高效代码)和动态分发(运行时查找具体实现)的原理及性能差异。
Rust中也有类似其他语言中的接口之类的特性,即trait,不过rust对其进行了增强,能实现许多功能
基本使用
pub trait Parser{
fn parse(&self, input: &str) -> String;
}
那么实现这个trait
struct CommonVideoParser;
impl Parser for CommonVideoParser{
fn parse(&self, input: &str) -> String {
fomat!("Parsed: {}", input)
}
}
除此之外,也能进行类似继承和多继承的操作
pub trait Parser: Send {
fn parse(&self, input: &str) -> String;
}
pub trait Parser: Send + Sync {
fn parse(&self, input : & str) -> String;
}
- Send是Rust提供的一种trait bound,用来约束实现者,主要是可以把这个类型的值转移到另外一个线程里
- Sync 可以把这个类型的引用
&T
安全地在线程之间共享
不同与接口的地方
trait约等于接口,但是比接口更强。
静态分发
编译器在编译的时候就知道了类型,直接生成高效代码, 这种泛型+trait的写法,类似于C++的模板:
fn run<T: Parser>(p: T) {
println!("{}", p.parse("hi"));
}
当我们传入CommonVideoParser的时候,编译器就知道了T的类型为CommonVideoParser(之前只知道p是一个实现了Parser trait的东西,但是具体是哪个东西不清楚),然后直接生成一份专门为CommonVideoParser写的run代码。
动态分发
类似java的多态,用虚表实现
fn run(p: &dyn Parser) {
println!("{}", p.parse("hi"));
}
在这个run中,当传入p为CommonVideoParser的时候,但是p是一个&dyn Parser
,所以编译器只知道p是一个实现了Parser trait的某个东西,但是具体的不清楚,需要再运行时候,根据需要去找具体的实现。类似于java的多态,性能低一点