ゲッター
CoddyのRustジャーニー「Object Oriented Programming」セクションの一部 — レッスン 11/61。
プライベートフィールドを使用すると、外部のコードは struct のデータに直接アクセスできなくなります。しかし、データを変更する権限を与えずに、他の人にデータを読み取らせる必要がある場合があります。そこでゲッターメソッドの出番です。
ゲッターは、単にプライベートフィールドへの参照を返すパブリックメソッドです。
// wallet.rs
pub struct Wallet {
balance: f64,
}
impl Wallet {
pub fn new(initial: f64) -> Wallet {
Wallet { balance: initial }
}
pub fn balance(&self) -> f64 {
self.balance
}
}
balance() メソッドは &self(読み取り専用アクセス)を受け取り、プライベートフィールドの値を返します。Rustでは、ゲッターは通常フィールドそのものにちなんで命名されます。get_ プレフィックスは必要ありません。
これで、外部のコードからメソッドを通じて残高を読み取ることができるようになります:
// main.rs
mod wallet;
use wallet::Wallet;
fn main() {
let w = Wallet::new(100.0);
println!("Balance: {}", w.balance()); // 動作します!
}
Stringのような所有権を持つデータを含むフィールドでは、不必要なコピーを避けるために、しばしば参照を返します:
pub fn name(&self) -> &String {
&self.name
}
ゲッターは、フィールド自体を保護しながら、制御された読み取りアクセスを提供します。構造体(struct)はそのデータの管理権限を保持し続け、外部コードは参照はできても変更はできません。
チャレンジ
簡単ゲッターメソッドがプライベートデータへの制御された読み取りアクセスをどのように提供するかを示す、ユーザープロファイルシステムを構築しましょう。
コードを整理するために、2つのファイルを作成します:
profile.rs: 2つのプライベートフィールド、username(String) とage(u32) を持つUserProfile構造体を定義します。構造体自体はパブリックにする必要がありますが、フィールドはプライベートのままにしてください。usernameとageを受け取るパブリックなnewコンストラクタを実装します。その後、2つのゲッターメソッドを追加します:username— ユーザー名への参照 (&String) を返しますage— 年齢の値 (u32) を返します
main.rs: profileモジュールを取り込み、UserProfileを作成し、ゲッターメソッドを使用してユーザー情報を出力します。
Rustのゲッターは通常、フィールド名そのものにちなんで命名されることを忘れないでください。get_ プレフィックスは不要です。String フィールドの場合は、不必要なコピーを避けるために参照を返します。
出力は次の正確な形式に従う必要があります:
Username: {username}
Age: {age}例えば、ユーザー名が "alice" で年齢が 25 のプロファイルを作成した場合、出力は次のようになります:
Username: alice
Age: 25ユーザー名と年齢の2つの入力を受け取ります。
チートシート
ゲッターメソッドは、プライベートなフィールドに対して読み取り専用のアクセスを提供するパブリックメソッドです。
ゲッターを使用すると、外部のコードがデータを直接変更することなく、データを参照できるようになります。
pub struct Wallet {
balance: f64,
}
impl Wallet {
pub fn new(initial: f64) -> Wallet {
Wallet { balance: initial }
}
pub fn balance(&self) -> f64 {
self.balance
}
}
Rustでは、ゲッターはフィールドそのものの名前で命名されます。get_ という接頭辞は必要ありません。
String のような所有権を持つデータを含むフィールドの場合は、不必要なコピーを避けるために参照を返します。
pub fn name(&self) -> &String {
&self.name
}
ゲッターメソッドの使用例:
let w = Wallet::new(100.0);
println!("Balance: {}", w.balance());
自分で試してみよう
mod profile;
use profile::UserProfile;
fn main() {
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let username = input1.trim().to_string();
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let age: u32 = input2.trim().parse().expect("Failed to parse age");
// TODO: コンストラクタを使用して UserProfile を作成する
// TODO: ゲッターメソッドを使用して username と age を表示する
// 形式:
// Username: {username}
// Age: {age}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。