作者:
yam276 ('_')
2025-04-28 15:40:36: https://space.bilibili.com/361469957/lists/3902595
: 從入門到入門
1. struct 的 impl function
就是其他語言的 class member function
類似許多語言 作為 member 要有 self 才能被實現
如 fn do(&self, ..)
沒有 self 的只能用命名空間使用
如 SomeThing::do_something();
參數種類有 (&self)、(&mut self)、(self)
第一個是不可變引用
第二個是可變引用
第三個是會讓 function 取得 struct 所有權
i.e. 可以利用第三個特性做 Building Pattern
struct ConfigBuilder { foo: String }
impl ConfigBuilder {
fn set_foo(mut self, f: String) -> Self {
self.foo = f;
self
}
fn build(self) -> Config {
Config { foo: self.foo }
}
}
呼叫時像這樣:
let config = ConfigBuilder
.set_foo("value".into())
.build();
這樣一整串方法都是以 self 傳遞所有權的方式來實作
2. 關聯函數
不用上面幾種 self 當第一個參數
就只能稱為關聯函數 (associated function)
不能說是 member function
類似C++的靜態函數 (無this指標)
也可以這樣寫
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
這樣會讓Self對照變成struct的Rectangle來輸出一個長寬大小為size的自己
大部分的 fn new() 都是這種如 String::new()
3. 調用函數
調用函數其實也是語法糖:
rect1.can_hold(&rect2)
// 等同
Rectangle::can_hold(&rect1, &rect2));
所以調用 member function 不會失去所有權
4. #[derive(Copy, Clone)]
定義了 #[derive(Copy, Clone)] 的情況
輸入不再是 self 而是 *self
函數不會嘗試獲得所有權而是複製一份
參考以下:
#[derive(Copy, Clone)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn max(self, other: Self) -> Self {
let width = self.width.max(other.width);
let height = self.height.max(other.height);
Self { width, height }
}
}
fn main() {
let r1 = Rectangle { width: 10, height: 20 };
let r2 = Rectangle { width: 30, height: 15 };
let r3 = r1.max(r2); // OK:r1 和 r2 都是 Copy,不會 move
println!("r1 = {}x{}", r1.width, r1.height); // 可以繼續用 r1
println!("r2 = {}x{}", r2.width, r2.height); // 可以繼續用 r2
}