Rust是強型別語言,執行嚴格的資料型別檢查,因此當定義使用某種型別參數的函式時比如說
square(x: f32) -> f32
調用函式的程式碼必須傳遞一個嚴格屬於這種型別的表達式例如
square(1.3414f32)
或者是每次使用該函式時都執行顯式的型別轉換例如
square(1.3414f64 as f32)
對於使用的人非常不方便,對於編寫該函式的人也不方便
由於Rust有很多數字類的型別,如果決定了參數型別是i32型別但每次調用幾乎都是用i64哪最好是更改參數型別為i64,而且如果函式有多個模塊或是多個程式在使用則很難滿足每個調用者的需求
例如
fn f(s: char, n1: i16, n2: i16) -> i16 {
if s == '1' {
return n1;
}
return n2;
}
println!("{}", f('1', 10, 20));
輸出
10
這時候想用f32當參數肯定是無法使用這函式,但總不能為了這個需求又寫了邏輯一樣的函式只差在參數不同,這時候就可以使用泛型函式了
fn main() {
println!("{}", f::<i16>('1', 10, 20));
println!("{}", f::<f32>('1', 10.1, 20.1));
}
fn f<T>(s: char, n1: T, n2: T) -> T {
if s == '1' {
return n1;
}
return n2;
}
輸出
10
10.1
這個函式既可以輸入i16也可以輸入f32當參數了
在定義函式中,函式名之後用<>包起來字母T,該字母為函式宣告的型別參數
這個表示宣告的不是具體函式而是由T型別參數來參數化的泛型函式,只有在編譯時為該T參數指定具體型別時該函式才成為具體函式
在使用泛型函式需要將T參數替換成實際使用f::的型別來護得具體函式
上面例子有三個地方宣告成T型別,在使用時需要三個都是相同型別不然在編譯時會出現錯誤
可以透過Rust的型別推斷簡化成下面使用範例
fn main() {
println!("{}", f('1', 10, 20)); // 透別推斷型別簡化
println!("{}", f('1', 10.1, 20.1)); // 透別推斷型別簡化
}
fn f<T>(s: char, n1: T, n2: T) -> T {
if s == '1' {
return n1;
}
return n2;
}