在學習了rust的泛型後, 我想寫乙個demo code用來練習。於是想到我要相加兩個數,無論是i8, i32, isize或是float型別。 於是很自然的想到如下實現,結果報錯 :
error[e0369]: cannot add `t` to `t`
編譯為什麼會報錯呢?
1 fn add(a:t,b:t) -> t5 6 fn main()",result);
10 }
在解釋這個問題之前,我們可以這樣假設,泛型是一種抽象,雖然我們傳入的是基本型別,但是架不住呼叫這個函式的人傳其它的type進去。這樣一來,比如泛型結構體相加是個什麼鬼呢?
1fn main() ;
3struct int_b;
4 let a:int_a= ;
5 let b:int_b= ;
6add(a,b);
7 }
既然泛型無法相加,那基本型別的泛型相加應該要如何實現呢? 如下,無符號整形,有符號整形,浮點型別相加 :
1 add(3,2);2 add(3.1,2,3
);3 add(5,-10);
首先映入腦海的是,如果利用泛型約束,是不是就可以做到了呢。為此,我們可以測試如下,結果編譯又報錯 :
error[e0404]: expected trait, found builtin type `i8`
1 fn add(a:t,b:t) ->t 56fn main()
",result);
1011 let result = add(5.2,3.3
);12 println!("
add result float :{}
",result);
13 }
好吧,在《rust by example》中,我們看到這樣一句話 :when working with generics, the type parametersoften must use traits as boundsto stipulate what functionality a type implements
必須要使用trait做為約束才可以。 為什麼會有這種規定呢? 按我的理解,如果用具體型別做為約束,那泛型完全失去了抽象的能力,上面的函式退化為如下,這樣就沒有意義了 :
1 fn add (a:i8,b:i8) ->i8
至此, 還是沒能解決我們泛型相加的問題. 不過,rust錯誤資訊給了我們乙個提示,泛型需要使用trait約束,那我們就宣告乙個trait作為約束好了。很自然的我們能想到,要怎樣定義trait才能達到約束的目的。我們只想限定基本型別,那就是說只有實現了add trait的型別才能作為我們的泛型約束。
1trait add
4 impl add for
i87 impl add for
i1610 impl add for
u3213 impl add for
usize
1617 fn add>(a:t,b:t) ->t
2122
fn main()
",result);
2627 let result =add(5u32,3u32);
28 println!("
add result u32 :{}
",result);
29 }
很不幸,這樣還是報錯:
error[e0369]: cannot add `t` to `t`
help: consider further restricting this bound
fn add+ std::ops::add>(a:t,b:t) -> t
泛型 泛型類 泛型方法 泛型擦除
1 是什麼?一種允許我們在不確定引數型別時候使用的型別。例如我不知道a方法應該會傳string還是int,我就用個泛型先佔坑。2 為什麼要用泛型?泛型可以在編譯期自動確定具體型別,檢查型別是否匹配,可以提高 的重用率,減少冗餘編碼。3 泛型與object的區別?像上面說的我不知道方法a的引數型別,其...
泛型 (2)泛型類 泛型方法 泛型介面
一 泛型類 定義person類 package cn.itcast.p2.bean public class person implements comparable public person string name,int age public int compareto person p ov...
泛型 泛型介面
泛型介面 介面上要宣告泛型,介面的抽象方法要接這個泛型。實現類的宣告也要寫具體的泛型實參。注意 泛型實參要用引用資料型別。基本資料型別不行。如果一定要使用基本資料型別那麼得使用基本資料型別的包裝類。如果實現類中的型別不確定,也想帶泛型,並且和介面中的一致。那麼在實現類中宣告,將在此處宣告的 類的泛型...