Publicキーワード
CoddyのRustジャーニー「Object Oriented Programming」セクションの一部 — レッスン 9/61。
前のレッスンでは、コードを個別のモジュールファイルに整理する方法を学びました。しかし、main.rs から Player 構造体を使用しようとすると、コンパイルエラーが発生します。これは、Rustのモジュール内のすべてが デフォルトで非公開(private) であるためです。
アイテムをモジュールの外部からアクセス可能にするには、それらを明示的に pub キーワードでマークする必要があります:
// player.rs
pub struct Player {
pub name: String,
pub score: u32,
}
impl Player {
pub fn new(name: String) -> Player {
Player { name, score: 0 }
}
}
pubが、構造体自体、各フィールド、そしてメソッドといった複数の場所に現れていることに注目してください。各項目には、それぞれ独自の可視性宣言が必要です。
structにpubが付いていないと、他のファイルはその型を名前で参照することさえできません。フィールドにpubが付いていないと、データに直接アクセスすることはできません。メソッドにpubが付いていないと、それらを呼び出すことはできません。
これで、main.rs 内でモジュールのパブリックな項目を使用できるようになります:
// main.rs
mod player;
use player::Player;
fn main() {
let p = Player::new(String::from("Alice"));
println!("{}", p.name);
}
use 文は Player をスコープに取り込むため、毎回 player::Player と書く必要がなくなります。この「デフォルトで非公開」というアプローチは意図的なものです。これにより、コードのどの部分を外部に公開すべきかを慎重に検討するよう促されます。
チャレンジ
簡単コードを2つのファイルに整理し、適切な項目を公開(public)にすることで、メインプログラムから使用できるようにして、シンプルな製品カタログを作成しましょう。
2つのファイルを作成します:
product.rs:name(String) とprice(f64) の2つのフィールドを持つProduct構造体を定義します。名前と価格を受け取り、新しいProductを返すnewという名前の関連関数を追加してください。構造体、そのフィールド、およびメソッドをモジュールの外部からアクセスできるように、公開(public)としてマークすることを忘れないでください。main.rs: product モジュールを宣言し、use文を使ってProductをスコープに取り込みます。その後、製品を作成し、その詳細をプリントします。
pub キーワードがどこに必要なのかを慎重に考えてください。構造体自体が可視である必要があり、フィールドは読み取りのためにアクセス可能である必要があり、コンストラクタメソッドは main.rs から呼び出し可能である必要があります。
出力は以下の正確な形式に従う必要があります:
Product: {name}, Price: ${price}例えば、名前が "Laptop" で価格が 999.99 の製品を作成した場合、出力は以下のようになります:
Product: Laptop, Price: $999.99製品名と価格の2つの入力を受け取ります。
チートシート
Rustでは、モジュール内のすべてのものはデフォルトで非公開です。モジュールの外部からアイテムにアクセスできるようにするには、pubキーワードを使用します。
構造体、フィールド、およびメソッドを公開としてマークします:
// player.rs
pub struct Player {
pub name: String,
pub score: u32,
}
impl Player {
pub fn new(name: String) -> Player {
Player { name, score: 0 }
}
}
各アイテムには独自の可視性宣言が必要です:
- 構造体に
pubを付けると、型が可視になります - フィールドに
pubを付けると、データへの直接アクセスが可能になります - メソッドに
pubを付けると、それらを呼び出すことが可能になります
useステートメントを使用して、アイテムをスコープに取り込みます:
// main.rs
mod player;
use player::Player;
fn main() {
let p = Player::new(String::from("Alice"));
println!("{}", p.name);
}
自分で試してみよう
// productモジュールを宣言する
mod product;
// TODO: use文を使用してProductをスコープに取り込む
fn main() {
// 入力を読み込む
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
let mut price_input = String::new();
std::io::stdin().read_line(&mut price_input).expect("Failed to read line");
let price: f64 = price_input.trim().parse().expect("Failed to parse price");
// TODO: Product::new関数を使用して新しいProductを作成する
// TODO: 次の形式で製品の詳細を表示する:
// Product: {name}, Price: ${price}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。