Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Rust辞典

  1. トップページ
  2. Rust辞典
  3. impl / メソッド定義

impl / メソッド定義

Rustでは『impl』ブロックを使って構造体にメソッドを追加します。『&self』を受け取るインスタンスメソッドと、selfを受け取らない関連関数(コンストラクタなど)の2種類が定義できます。

構文
struct Rectangle {
    width: f64,
    height: f64,
}

impl Rectangle {
    // 関連関数(コンストラクタ): selfを受け取りません。
    fn new(width: f64, height: f64) -> Self {
        Rectangle { width, height }
    }

    // インスタンスメソッド: &self で不変参照を受け取ります。
    fn area(&self) -> f64 {
        self.width * self.height
    }

    // &mut self で可変参照を受け取り、フィールドを変更します。
    fn scale(&mut self, factor: f64) {
        self.width *= factor;
        self.height *= factor;
    }
}

// 呼び出し方です。
let mut r = Rectangle::new(5.0, 3.0);  // 関連関数は :: で呼び出します。
println!("{}", r.area());              // メソッドは . で呼び出します。
r.scale(2.0);
メソッドの種類
シグネチャ概要
fn method(&self)不変参照を受け取るインスタンスメソッドです。
fn method(&mut self)可変参照を受け取るインスタンスメソッドです(フィールドの変更が可能)。
fn method(self)所有権を受け取るメソッドです(呼び出し後にインスタンスは使えません)。
fn func() -> Selfselfを受け取らない関連関数(コンストラクタなどに使います)。
Selfimpl 対象の型自身を指す型エイリアスです。型名の代わりに使えます。
サンプルコード
#[derive(Debug)]
struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

impl Circle {
    // 関連関数(コンストラクタ)です。
    fn new(x: f64, y: f64, radius: f64) -> Self {
        Circle { x, y, radius }
    }

    // 原点に置かれた円を作るファクトリ関数です。
    fn at_origin(radius: f64) -> Self {
        Circle::new(0.0, 0.0, radius)
    }

    // &self: 読み取り専用のメソッドです。
    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }

    fn circumference(&self) -> f64 {
        2.0 * std::f64::consts::PI * self.radius
    }

    fn contains(&self, x: f64, y: f64) -> bool {
        let dx = self.x - x;
        let dy = self.y - y;
        (dx * dx + dy * dy).sqrt() <= self.radius
    }

    // &mut self: フィールドを変更するメソッドです。
    fn move_to(&mut self, x: f64, y: f64) {
        self.x = x;
        self.y = y;
    }

    fn resize(&mut self, new_radius: f64) {
        self.radius = new_radius;
    }
}

// impl ブロックは複数に分けても構いません。
impl Circle {
    fn description(&self) -> String {
        format!(
            "Circle at ({}, {}) with radius {}",
            self.x, self.y, self.radius
        )
    }
}

fn main() {
    // 関連関数でインスタンスを生成します。
    let mut c = Circle::new(0.0, 0.0, 5.0);
    println!("{:?}", c);

    // メソッドを呼び出します。
    println!("面積: {:.2}", c.area());
    println!("周囲: {:.2}", c.circumference());
    println!("(3,4)を含む?: {}", c.contains(3.0, 4.0));  // true(距離5)
    println!("(4,4)を含む?: {}", c.contains(4.0, 4.0));  // false(距離5.65...)

    // &mut self メソッドで状態を変更します。
    c.move_to(10.0, 20.0);
    c.resize(3.0);
    println!("{}", c.description());

    // 別のコンストラクタです。
    let c2 = Circle::at_origin(1.0);
    println!("{:?}", c2);
}
概要

Rustのメソッドは『impl』ブロック内に定義します。同じ型に対して複数の『impl』ブロックを書くことが可能で、機能ごとに分けて整理できます。

関連関数は型名に『::』を付けて呼び出します(例: 『Circle::new()』)。Rustにはコンストラクタのための特別な構文はなく、慣習として『new()』という名前の関連関数を使います。

構造体の定義は『struct / フィールド定義』を、traitの実装は『trait / impl Trait for 型』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。