1. 方法 (method)
方法定義在 impl 區塊裡,第一個參數必須是 self(或 &self、&mut self),代表該結構體的實例,呼叫方式跟函數不同,會用實例.方法()。
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
println!("The area is {}", rect.area());
}
輸出:
The area is 1500
2. 可變方法
如果方法需要修改實例,必須用 &mut self,這和之前學到的變數 mut 一樣,是顯式要求修改權限的設計。。
struct Counter {
value: i32,
}
impl Counter {
fn increase(&mut self) {
self.value += 1;
}
}
fn main() {
let mut c = Counter { value: 0 };
c.increase();
println!("Counter = {}", c.value);
}
輸出:
Counter = 1
3. 關聯函數 (Associated Functions)
沒有 self 參數,通常當作建構函數使用,呼叫方式是 ::。
struct Person {
name: String,
age: u8,
}
impl Person {
fn new(name: &str, age: u8) -> Person {
Person {
name: String::from(name),
age,
}
}
}
fn main() {
let p = Person::new("Alice", 20);
println!("{} is {} years old", p.name, p.age);
}
輸出:
Alice is 20 years old
4. 多個 impl 區塊
一個 struct 可以有多個 impl 區塊,讓程式碼更好維護。
struct Circle {
radius: f64,
}
impl Circle {
fn area(&self) -> f64 {
3.14 * self.radius * self.radius
}
}
impl Circle {
fn circumference(&self) -> f64 {
2.0 * 3.14 * self.radius
}
}
fn main() {
let c = Circle { radius: 5.0 };
println!("Area = {}", c.area());
println!("Circumference = {}", c.circumference());
}
輸出:
Area = 78.5
Circumference = 31.400000000000002
5. 學習心得與補充
今天學到的 impl 讓我覺得 struct 變得更完整了。昨天 struct 還只是單純的資料容器,但今天加上方法之後,就能直接把行為綁定到資料上,寫起來也更自然。這也和前幾天的借用規則串了起來,如果方法只需要讀取就用 &self,要修改就用 &mut self。另外,關聯函數讓我想到 C++ 的 static function,不過在 Rust 裡更常用來當建構函數,像 Person::new() 這樣的語法就讓程式碼很清楚。今天學到的方法和關聯函數讓我開始體會到 Rust 在物件導向上的另一種做法:不用繼承和類別系統,也能用簡單的 impl 來組織程式碼,讓資料和行為自然地綁在一起。