创建网站的六个步骤,wordpress创建页面,thinkphp 网站开发,海口网站开发Rust的运行时多态
Rust的静态多态即编译时多态#xff0c;通过**泛型特征约束#xff08;Generic Type Trait Constrait#xff09;**来实现#xff1b;
那么动态多态#xff08;运行时多态#xff09;呢#xff1f;答案是特征对象#xff08;Trait Object#xff…Rust的运行时多态
Rust的静态多态即编译时多态通过**泛型特征约束Generic Type Trait Constrait**来实现
那么动态多态运行时多态呢答案是特征对象Trait Object。
特征对象不是一个实例而是一个结构体类型。
语法是dyn TraitName编译时指示某个对象是实现TraitName的类型其具体类型未知。
分析
程序运行时要调用一个特征方法需要两个要素
对象实例对象类型未知因此其编译期大小未知特征的方法表
所以特征对象结构体必须获知以上两个要素。
发生运行时多态时在编译阶段编译器无法辨别对象实例的类型因此对象实例要素的大小无法获知进而特征对象Trait Object的大小在编译阶段无法被确定这决定了Trait Object只能存放在堆上通过引用或智能指针来访问。
指向特征对象的引用或智能指针包含了两个指针成员在程序运行时ptr1在指向对象实例ptr2指向该对象类型的Trait Method实现。
典型用例 #[derive(Debug)]
struct Journal {author: String,year: u16,from: String,
}
#[derive(Debug)]
struct Conference {author: String,year: u16,country: String,
}trait Summary {fn summary(self) - String;
}impl std::fmt::Debug for dyn Summary {fn fmt(self, f: mut std::fmt::Formatter) - std::fmt::Result {write!(f, {}, self.summary())}
}impl Summary for Journal {fn summary(self) - String {format!({}\t{}\t{}, self.author, self.year, self.from)}
}
impl Summary for Conference {fn summary(self) - String {format!({}\t{}\t{}, self.author, self.year, self.country)}
}// cant defer concrete type in compile stage, trait constrain cant used here
// fn init_default(_type: str) - impl Summary {
// if _type journal {
// Journal {
// author: hjd.to_owned(),
// year: 2018,
// from: Nature.to_owned(),
// }
// } else {
// Conference {
// author: hjd.to_owned(),
// year: 2018,
// country: China.to_owned(),
// }
// }
// }// 只能使用特征对象进行动态分发因为返回类型编译期无法推理获知
fn init_default(_type: str) - Boxdyn Summary {if _type journal {Box::new(Journal {author: hjd.to_owned(),year: 2018,from: Nature.to_owned(),})} else {Box::new(Conference {author: hjd.to_owned(),year: 2018,country: China.to_owned(),})}
}fn main() {let p1 init_default(journal);let p2 init_default(conference);let p3 init_default(journal);let p4 init_default(conference);let p_list vec![p1, p2, p3, p4];// dyn Summary是一个特征对象类型它忘记了自己之前的具体类型只能调用Summary特征中的方法for p in p_list.iter() {println!({:?}, p);}
}