100日後にRustをちょっと知ってる人になる: [Day 84]書籍: Rust プログラミング完全ガイド その8
Day 84 のテーマ
Day 83 までに Rust の書籍の Rustプログラミング完全ガイド の 1 章から 17 章までを読み終わりました。
- 第1章 Rustを始めよう
- 第2章 数値演算などの基本を把握しよう
- 第3章 オブジェクトに名前を付ける
- 第4章 実行の流れを制御する
- 第5章 データシーケンスを使う
- 第6章 基本のデータ型を使う
- 第7章 列挙と照合
- 第8章 混成的なデータ構造を使う
- 第9章 関数を定義する
- 第10章 ジェネリックな関数や型を定義する
- 第11章 メモリを割り当てる
- 第12章 データの実装
- 第13章 クロージャを定義する
- 第14章 変更可能な文字列を使う
- 第15章 範囲とスライス
- 第16章 イテレータを使う
- 第17章 入出力とエラー処理
- 第18章 データのカプセル化[メソッドとモジュール]
- 第19章 トレイトを使う
- 第20章 オブジェクト指向プログラミング
- 第21章 標準ライブラリのコレクション
- 第22章 所有権、移動、コピー
- 第23章 借用とライフタイム
- 第24章 さらにライフタイムについて
1 週間でそこそこ読み進めて、残り 7 章となりました。この勢いで読めるのも、多少は Rust のことが分かるようになってきているからなのかなと思いつつも、まだまだだと思わざるを得ない Rust 力なのでした。今日もまた読み進めていきます。
第18章 データのカプセル化[メソッドとモジュール]
この章での内容:
- 関数を呼び出すのに、なぜ関数型記法よりドット記法のほうが便利なのか
- ドット記法を使って呼び出せる関数の宣言で、
impl
とself
のキーワードを使う方法 - 関数宣言をモジュールに入れてカプセル化し、特定の関数だけを他のモジュールからアクセスできるようにする方法
- モジュールの階層構造を作り、その階層構造に属する任意の関数をアクセスする方法
- 型の別名 (エイリアス) を定義する方法
関数呼び出しの記法についてメモ
-
関数型記法
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
は可変なリファレンス
Self
と self
は別のキーワードです。Self
は self
の型を示しています。
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 では private
や public
というキーワードを使って可視性をコントロールしていました。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章 データのカプセル化[メソッドとモジュール]
- 関数を呼び出すのに、なぜ関数型記法よりドット記法のほうが便利なのか
- ドット記法を使って呼び出せる関数の宣言で、
impl
とself
のキーワードを使う方法 - 関数宣言をモジュールに入れてカプセル化し、特定の関数だけを他のモジュールからアクセスできるようにする方法
- モジュールの階層構造を作り、その階層構造に属する任意の関数をアクセスする方法
- 型の別名 (エイリアス) を定義する方法
Discussion