導入
構造体に「振る舞い(メソッド)」を持たせると、データと処理がまとまって扱いやすくなります。Rust では impl ブロックにメソッドを書きます。ここでも第一引数の &self に、所有権・借用の考え方が顔を出します。
説明
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
// メソッド: 第一引数は &self(自分自身への参照)
fn area(&self) -> u32 {
self.width * self.height
}
// 関連関数: self を取らない。よく「コンストラクタ」に使う
fn new(width: u32, height: u32) -> Rectangle {
Rectangle { width, height } // フィールド名と変数名が同じなら省略できる
}
}
fn main() {
let rect = Rectangle::new(30, 50); // 関連関数は 型名:: で呼ぶ
println!("面積: {}", rect.area()); // メソッドは インスタンス. で呼ぶ
}
impl Rectangle { ... }…Rectangleのメソッドをまとめる場所。fn area(&self)… 第一引数&selfは「自分自身への不変参照」。読むだけなので&self。中身を変更するメソッドなら&mut self、自分を消費(ムーブ)するならselfを取ります。ここでも借用のルールがそのまま働きます。fn new(...)…selfを取らない 関連関数。Rectangle::new(...)のように型名から呼び、インスタンス生成によく使います(Rust に「コンストラクタ」構文はなく、慣習としてnewを書きます)。Rectangle { width, height }… 変数名とフィールド名が同じときはwidth: widthをwidthと省略できます。
&self にするか &mut self にするか self にするかで、「このメソッドは自分を読むだけか、書き換えるか、消費するか」が型に表れます。所有権の考え方が、そのままAPIの設計になるわけです。
試すには
area(&self) の中で self.width = 0; と書き換えようとするとエラーになります(&self は不変借用だから)。書き換えたいメソッドは &mut self にする必要があります。メソッドのレシーバにも借用ルールが一貫して効いています。