1. Rust的特征與泛型
1.1 先上特征代碼:
use std::boxed::Box;
// 定義一個特征
pub trait Animal{
fn bark(&self);
}
pub struct Dog{
pub name: String,
}
pub struct Chicken{
pub name: String,
}
// 實作一個特征
impl Animal for Dog{
fn bark(&self){
println!("{} : wang wang wang !",&self.name)
}
}
// 實作特征
impl Animal for Chicken{
fn bark(&self){
println!("{} : ji ji ji ~",&self.name)
}
}
pub struct Zoo{
// 用一個list裝動物
pub components: Vec<Box<dyn Animal>>,
}
// 給Zoo實作一個方法
impl Zoo{
pub fn run(&self){
for c in self.components.iter() {
c.bark();
}
}
}
為什麼先上代碼? 因為這就要先從代碼說起來了,把代碼貼出來和Java的代碼進行對比可能更加明确。
從代碼看來,Rust中的trait和Java中的接口非常相似,都是用來定義一組行為。
運作代碼:
use animal::{Zoo,Chicken,Dog};
fn main() {
// 執行個體化結構體,并放入了兩個對象
let zoo = Zoo{
components: vec![
Box::new(Chicken{
name: String::from("xiao ji"),
}),
Box::new(Dog{
name: String::from("旺财"),
}),
],
};
zoo.run();
}
運作結果:
xiao ji is bark
旺财 is bark
1.2 泛型代碼
上代碼:
pub trait Animal{
fn bark(&self);
}
pub struct Dog{
pub name: String,
}
pub struct Chicken{
pub name: String,
}
impl Animal for Dog{
fn bark(&self){
println!("{} is bark",&self.name)
}
}
impl Animal for Chicken{
fn bark(&self){
println!("{} is bark",&self.name)
}
}
// 把特征換成泛型
pub struct Zoo<T: Animal>{
pub components: Vec<T>,
}
impl <T> Zoo<T> where T: Animal{
pub fn run(&self){
for c in self.components.iter() {
c.bark();
}
}
}
代碼沒有大的改變,将集合中使用trait改為泛型。
主代碼不變,然後編譯代碼,出現如下錯誤
160 | pub struct Box<T: ?Sized>(Unique<T>);
| ------------------------------------- doesn't satisfy `std::boxed::Box<animal::Chicken>: animal::Animal`
|
= note: the method `run` exists but the following trait bounds were not satisfied:
`std::boxed::Box<animal::Chicken>: animal::Animal`
1.2 出現問題的原因?
Rust與Java不同, 在Java中,可能接口和泛型,都可以使用,代表一類類型,但是在Rust中,竟然不可以,這是為什麼呢?
在Rust中, 由于安全性考慮,在使用泛型的時候,類型由第一個個對象确定了, 在編譯的時候,發現後邊的類型與第一個類型不同,則會出現這樣的錯誤。
1.3 結論
在Rust中使用泛型和特征的時候要注意,可能特種更符合Java中的接口與泛型。而Rust泛型由于在編譯的時候确定了類型,反而有些像數組,确定了唯一類型,隻能放一種類型。
你的每一個點贊,我都當做喜歡