🦀

100日後にRustをちょっと知ってる人になる: [Day 84]書籍: Rust プログラミング完全ガイド その8

2022/12/11に公開

Day 84 のテーマ

Day 83 までに Rust の書籍の Rustプログラミング完全ガイド の 1 章から 17 章までを読み終わりました。

1 週間でそこそこ読み進めて、残り 7 章となりました。この勢いで読めるのも、多少は Rust のことが分かるようになってきているからなのかなと思いつつも、まだまだだと思わざるを得ない Rust 力なのでした。今日もまた読み進めていきます。

第18章 データのカプセル化[メソッドとモジュール]

この章での内容:

  • 関数を呼び出すのに、なぜ関数型記法よりドット記法のほうが便利なのか
  • ドット記法を使って呼び出せる関数の宣言で、implself のキーワードを使う方法
  • 関数宣言をモジュールに入れてカプセル化し、特定の関数だけを他のモジュールからアクセスできるようにする方法
  • モジュールの階層構造を作り、その階層構造に属する任意の関数をアクセスする方法
  • 型の別名 (エイリアス) を定義する方法

関数呼び出しの記法についてメモ

  • 関数型記法
    • f(x, y)
  • ドット記法
    • x.f(y)

ドット記法で呼び出せる関数は、すべて関数型記法で呼び出すことが可能です。

println!("関数型記法:{} ドット記法:{}",
    "Hello Rust".to_string(),
    std::string::ToString::to_string("Hello Rust")
);

メソッドの定義について

ある特定の型に関連づいている関数のことをメソッドと呼びます。

ここで構造体を使って Person 型を定義します。この型に関連付ける関数 (メソッド) の定義を行うために impl キーワードを使用して構造体に実装を行います。

struct Person {
    first_name: String,
    last_name: String,
}

impl Person {
    fn naming(&self) -> String {
        format!("氏名: {} {}", self.first_name, self.last_name)
    }
}

let me = Person {
    first_name: "Shinya".to_string(),
    last_name: "Yanagihara".to_string(),
};

println!("{}", me.naming());

self と Self についてメモ

self キーワードは、Java の this キーワードと同様で、このメソッドが適用されている現在のオブジェクトを表現するものです。ただし、異なる以下のような異なる点があります:

  • self が必要な場合、シグネチャで指定する必要がある
  • self は暗黙的に指定されない。現在のオブジェクトにアクセスする場合、フィールド名あるいはメソッド名の前に self を指定する必要がある
  • self は現在のオブジェクトを示す。リファレンスではない。
  • &self は非可変なリファレンス
  • &mut self は可変なリファレンス

Selfself は別のキーワードです。Selfself の型を示しています。

new 関数を定義して Self 型オブジェクトの生成を行うようにしました。この関数には引数がないところがポイントです。そのため、これはメソッドとは呼ばずに、関連関数と呼びます。

struct Person {
    first_name: String,
    last_name: String,
}

impl Person {
    fn new() -> Self {
        Self {
            first_name: String::new(),
            last_name: String::new(),
        }
    }

    fn naming(&self) -> String {
        format!("氏名: {} {}", self.first_name, self.last_name)
    }
}

let mut me = Person::new();
println!("{}", me.naming());

me.first_name = "Shinya".to_string();
me.last_name = "Yanagihara".to_string();
println!("{}", me.naming());

mod キーワードと pub キーワードについてメモ

Java では privatepublic というキーワードを使って可視性をコントロールしていました。Rust ではモジュールという考え方を使って制御します。

以下のコードは、ブロックの内側のコードに外側からはスコープが異なるためアクセスできません。

{
    fn f() -> String { g() }
    fn g() -> String { "Hello Rust".to_string() }
}
println!("{}", f());

そこでモジュール mod を利用します。

mod sub_module {
    pub fn f() -> String { g() }
    fn g() -> String { "Hello Rust".to_string() }
}
println!("{}", sub_module::f());

Day 84 のまとめ

今日読んだのは 1 章だけでしたが、改めて構造体とメソッド、そして self の使い方などについて確認をすることができました。
公式のリファレンスの構造体に関する章の内容がいろいろと腑に落ちた気がしました。

以下の内容が今日復習したことです。

  • 第18章 データのカプセル化[メソッドとモジュール]
    • 関数を呼び出すのに、なぜ関数型記法よりドット記法のほうが便利なのか
    • ドット記法を使って呼び出せる関数の宣言で、implself のキーワードを使う方法
    • 関数宣言をモジュールに入れてカプセル化し、特定の関数だけを他のモジュールからアクセスできるようにする方法
    • モジュールの階層構造を作り、その階層構造に属する任意の関数をアクセスする方法
    • 型の別名 (エイリアス) を定義する方法
GitHubで編集を提案

Discussion