前言
本系列文書寫我個人初探 Rust 的學習筆記,章節劃分主要基於著名的 The Book,The Rust Programming Language,程式碼部分通常是個人閱讀消化後以方便說明的方式撰寫,完整學習建議直接參見該書。
The Rust Programming Language
該書也有中文翻譯版,不過個人閱讀以英文原版為主以鞏固對 terminology 的一致認識,我認為對未來閱讀以及查找資料會較為順暢。
不論語言該書都是相當優秀的學習資源,選擇適合你的語言開始學習 Rust 吧。
Appendix F: Translations of the Book
泛型
泛型允許我們寫程式時定義一些未來才會指定的類型,這能讓方法或資料類型更有彈性。
function
如下所示,在不使用泛型的情況下,因為我們必須指定參數的類型,即使 function 內的程式邏輯幾乎完全相同我們也必須撰寫兩支 function。
fn main() {
print_number(5); // 5
print_str("My str"); // My str
}
fn print_number(num: i32){
println!("{num}");
}
fn print_str(s: &str){
println!("{s}");
}
可以用泛型簡化,泛型以 <> 定義,命名為 T 算是 naming convention,也可以自由命名。
use std::fmt::Display;
fn main() {
my_print(5);
my_print("My str");
}
fn my_print<T: Display>(content: T){
println!("{content}");
}
要注意的是呼叫 println! 需要實作 Display trait,因此這邊將 T 限縮為有實作 Display trait 的類型,trait 在下一章就會學習到,這邊稍微看過即可。
struct
struct 也可以使用泛型,這邊利用了複數個泛型讓 S 能夠儲存任意的資料類型。
#[derive(Debug)]
struct S<T, U> {
a: T,
b: U
}
fn main() {
let x = S {
a: String::from("test"),
b: 15
};
let y = S {
a: 1.5,
b: vec![1, 2, 3]
};
println!("{:?}", x); // S { a: "test", b: 15 }
println!("{:?}", y); // S { a: 1.5, b: [1, 2, 3] }
}
impl
implementation block 中使用泛型實作方法的寫法如下,需要在 impl 後先定義泛型才能為 S<T> 實作方法。
use std::fmt::Display;
struct S<T> {
a: T,
}
impl<T: Display> S<T>{
fn print_a(&self){
println!("{}", self.a);
}
}
fn main() {
let x = S {
a: String::from("test")
};
x.print_a(); // test
}
如果將 a 設為為實作 Display trait 的類型但呼叫 print_a 則會報錯。
let y = S {
a: vec![1, 2, 3]
};
y.print_a(); // ERROR
// the method `print_a` exists for struct `S<Vec<{integer}>>`,
// but its trait bounds were not satisfied
也可以只為特定類型實作方法,下面程式只為 i32 實作 print_a。
struct S<T> {
a: T,
}
impl S<i32>{
fn print_a(&self){
println!("{}", self.a);
}
}
fn main() {
let x = S {
a: 5
};
let y = S {
a: String::from("test")
};
x.print_a(); // 5
y.print_a(); // ERROR
// no method named `print_a` found for struct `S<String>` in the current scope
}
enum
enum 中使用的泛型已經不陌生,常用的 Option 和 Result 其實都是以泛型實作。
enum Option<T> {
Some(T),
None,
}
enum Result<T, E> {
Ok(T),
Err(E),
}