trait特性
trait特性可以理解为Java中的接口,具备和接口很类似的特性。trait中的函数叫做方法。某个结构体要么实现某个trait的全部方法,要么全部不实现。其中的impl trait特性也类似与java中返回一个接口对象。
在1.26版本后引入了存在类型(existential type的支持),这个特性就是通过impl trait实现,使得开发人员可以指定函数的返回类型,而不必具体指出是哪一种类型。
rust中返回trait对象的方法
方法一:引入Box
众所周知,通过Box装饰的变量保存在堆中,而Box的大小是固定的,只是通过一个指针指向堆中的变量,这样就不会违背运行时必须知道返回值大小的语法,例子如下。
pub trait animal{
fn print_name(&self);
}
struct cat{
name:String
}
struct dog{
name:String
}
impl animal for cat{
fn print_name(&self){
println!("{}",self.name);
}
}
impl animal for dog{
fn print_name(&self){
println!("{}",self.name);
}
}
fn who(who:i32)->Box<dyn animal>{
if who== 1{
Box::new(cat{name:"cat".to_string()}) as Box<dyn animal>
} else{
Box::new(dog{name:"dog".to_string()}) as Box<dyn animal>
}
}
fn main(){
let a = who(1);
a.print_name();
}
方法二 impl trait
impl trait只能返回相同类型的trait。比如对比上面的Box的动态分配,
只能都返回cat或都返回dog。这样就决定了返回值的大小是固定的。
pub trait animal{
fn print_name(&self);
}
struct cat{
name:String
}
struct dog{
name:String
}
impl animal for cat{
fn print_name(&self){
println!("{}",self.name);
}
}
impl animal for dog{
fn print_name(&self){
println!("{}",self.name);
}
}
fn who(who:i32)->impl animal{ //注意只能返回同一个类型
if who== 1{
cat{name:"cat one ".to_string()}
} else{
cat{name:"cat two ".to_string()}
}
}
fn main(){
let a = who(1);
a.print_name();
}