Rustは、安全性とパフォーマンスを重視したプログラミング言語として多くの開発者に支持されています。その中でも、フィールドのプライバシー(公開/非公開)の設定は、コードの安全性を確保しつつモジュール間の適切なデータアクセスを設計する上で重要な役割を果たします。本記事では、Rustにおけるフィールドの公開範囲とモジュールの関係性を詳しく解説します。公開範囲の指定方法やモジュールの役割、具体的な実装例から得られる知見を通じて、フィールドプライバシー設定の基礎から応用までをわかりやすく説明していきます。
Rustにおけるプライバシーの基本概念
Rustでは、フィールドやメソッドの公開範囲を制御するために、アクセス修飾子が用意されています。これにより、データや機能をモジュール間で適切に共有し、外部からの不正アクセスを防ぐことができます。
アクセス修飾子の種類
Rustで使用される主なアクセス修飾子は以下の通りです:
private
- デフォルトの状態:モジュール外からはアクセスできません。
- フィールドやメソッドは、宣言されたモジュールの内部でのみ使用可能です。
- 外部からの直接的な操作を防ぎ、安全性を高めます。
pub
- 公開状態:モジュール外部からアクセス可能になります。
- モジュールやクレートの利用者に対して機能を提供したい場合に使用します。
pub(crate)
- クレート内で公開:同じクレート内ではアクセスできますが、他のクレートからは非公開です。
- 内部の実装を隠しつつ、クレート全体で共有したい場合に便利です。
pub(super)
- 親モジュールに対して公開:直接の親モジュールからアクセスできます。
- 親子モジュール間での限定的な公開に適しています。
フィールドのプライバシーの基本ルール
- Rustの構造体(struct)のフィールドはデフォルトで非公開(private)です。
- 必要に応じてpubやpub(crate)を使用して公開することで、他のモジュールやクレートから利用可能になります。
基本例
以下はフィールドの公開範囲の基本的な例です:
mod example {
pub struct PublicStruct {
pub public_field: i32, // 外部からアクセス可能
private_field: i32, // モジュール内でのみアクセス可能
}
impl PublicStruct {
pub fn new(public: i32, private: i32) -> PublicStruct {
PublicStruct {
public_field: public,
private_field: private,
}
}
pub fn get_private(&self) -> i32 {
self.private_field // 非公開フィールドの間接的なアクセス
}
}
}
この基本的な概念を理解することで、プログラム全体の構造を明確にし、適切なデータ管理が可能になります。次に、モジュールとの関係性について詳しく見ていきます。
モジュール構造とプライバシーの関係
Rustでは、モジュール(module)を使用してコードを論理的に分割できます。モジュール構造とフィールドの公開設定は密接に関連しており、モジュールをまたいだデータの共有や制御が可能です。
モジュールの基本構造
モジュールはmod
キーワードを使って定義され、モジュール内の要素(構造体、関数、定数など)の公開範囲を個別に設定できます。
mod outer {
pub mod inner {
pub struct MyStruct {
pub public_field: i32, // 完全に公開
private_field: i32, // モジュール内でのみアクセス可能
}
impl MyStruct {
pub fn new(val: i32) -> MyStruct {
MyStruct {
public_field: val,
private_field: val * 2,
}
}
pub fn get_private(&self) -> i32 {
self.private_field
}
}
}
}
モジュールの階層と公開範囲
Rustでは、モジュールが階層的に構造化されています。モジュール内で定義された要素の公開範囲は、アクセス修飾子によって制御されます。
- 非公開(private):定義されたモジュール内でのみアクセス可能。
- 公開(pub):モジュール外部でもアクセス可能。ただし、モジュールが外部に公開されている必要があります。
mod outer {
mod inner {
pub struct InnerStruct; // innerモジュール内では公開
}
pub mod public_inner {
pub struct PublicStruct; // outerモジュールの外でも公開
}
}
上記の例では、InnerStruct
はinner
モジュール内でしか使えませんが、PublicStruct
はouter
モジュールの外部からアクセスできます。
モジュール間でのアクセスと制限
モジュール間のアクセスには以下のルールが適用されます:
- 非公開(private)フィールドや関数は、同じモジュール内でのみアクセス可能です。
- 公開(pub)要素は外部から利用できますが、そのモジュールがさらに公開されていなければ外部クレートからはアクセスできません。
- 特定のモジュール内で共有したい場合は
pub(crate)
やpub(super)
を活用します。
具体例:モジュール間のフィールドアクセス
以下の例では、モジュール間での公開範囲を設定し、適切にアクセス制御を行っています。
mod library {
pub mod books {
pub struct Book {
pub title: String, // 外部からアクセス可能
pub(crate) author: String, // 同一クレート内でアクセス可能
pub(super) isbn: String, // 親モジュールからのみアクセス可能
private_notes: String, // モジュール内でのみアクセス可能
}
impl Book {
pub fn new(title: &str, author: &str, isbn: &str, notes: &str) -> Book {
Book {
title: title.to_string(),
author: author.to_string(),
isbn: isbn.to_string(),
private_notes: notes.to_string(),
}
}
}
}
}
fn main() {
let book = library::books::Book::new("Rust Book", "Author Name", "123456789", "Private Notes");
println!("Title: {}", book.title);
// println!("Author: {}", book.author); // エラー: pub(crate) で制限
// println!("ISBN: {}", book.isbn); // エラー: pub(super) で制限
}
モジュール構造のポイント
- 設計を明確に:モジュール間でのデータの流れを明確にする。
- アクセス範囲を限定:必要以上に公開範囲を広げないことで安全性を確保。
- 柔軟な公開設定:
pub(crate)
やpub(super)
を利用して、制御を細かく設定する。
これにより、モジュール間でのデータ共有が簡潔で安全になります。次に、フィールドを公開する場面と非公開にする場面について具体的に解説します。
フィールドを公開する場面と非公開にする場面
Rustのプライバシー設定を適切に使い分けることで、コードの安全性と保守性を向上させることができます。フィールドを公開または非公開にする判断基準を以下に詳しく解説します。
フィールドを公開する場面
フィールドをpub
やpub(crate)
で公開するのは、以下のような場面です。
1. 外部モジュールやクレートにデータを提供する場合
- 外部クレートやモジュールがフィールドの値を必要とする場合、
pub
を使用して公開します。 - 例:APIライブラリなどで利用者がデータに直接アクセスできる必要がある場合。
pub struct User {
pub name: String, // 利用者に名前を提供
pub age: u32, // 利用者が年齢を取得可能
}
2. テストやデバッグのためにアクセスが必要な場合
- 特定のユースケースで、データを直接確認できると便利です。
- この場合、
pub(crate)
や限定公開の設定を使うと過度な公開を避けられます。
pub(crate) struct DebugInfo {
pub(crate) details: String, // クレート内でのみ公開
}
3. 再利用性を高める場合
- フィールドを公開することで、再利用可能なモジュールや構造体として機能させます。
- 例:汎用データ構造(例:
Vec
やHashMap
)。
フィールドを非公開にする場面
フィールドを非公開(デフォルト)に設定するのは、以下のような場面です。
1. 内部実装を隠蔽する場合
- モジュールの内部状態を隠蔽することで、外部からの不正操作を防ぎます。
- 例:ライブラリ内部のデータ構造。
struct InternalData {
sensitive_info: String, // 非公開フィールド
}
2. フィールドの変更を制御したい場合
- 外部からの直接変更を禁止し、専用のメソッドでのみ操作可能にします。
- GetterやSetterを利用して、アクセスや操作を制御します。
pub struct Account {
balance: f64, // 非公開
}
impl Account {
pub fn new() -> Account {
Account { balance: 0.0 }
}
pub fn deposit(&mut self, amount: f64) {
self.balance += amount;
}
pub fn get_balance(&self) -> f64 {
self.balance
}
}
3. セキュリティやデータ整合性を確保したい場合
- 特定のロジックを通じてのみフィールドにアクセスさせることで、予期しないデータ不整合を防ぎます。
公開と非公開を組み合わせた例
以下は、公開と非公開のフィールドを適切に使い分けた例です:
pub struct Config {
pub(crate) settings: String, // 同一クレート内でのみ公開
private_data: String, // モジュール内のみ
}
impl Config {
pub fn new(settings: &str, private_data: &str) -> Config {
Config {
settings: settings.to_string(),
private_data: private_data.to_string(),
}
}
pub fn get_private_data(&self) -> &str {
&self.private_data // 非公開フィールドを間接的に提供
}
}
まとめ
- 公開:必要最小限のフィールドのみ公開し、他のモジュールやクレートが利用できるようにする。
- 非公開:外部からの直接アクセスを避けたいフィールドは非公開に設定し、安全性や保守性を向上させる。
- 柔軟な設計:
pub(crate)
やpub(super)
を活用して、公開範囲を細かく制御する。
このように適切なプライバシー設定を行うことで、モジュール間の依存関係を明確化し、コードの安定性を確保できます。次に、pub(crate)
やpub(super)
といった特殊な公開範囲の指定方法について詳しく解説します。
pub(crate)やpub(super)の使い方
Rustでは、フィールドやメソッドの公開範囲を細かく制御するために、pub(crate)
やpub(super)
といった特殊なアクセス修飾子が提供されています。これらを適切に活用することで、モジュール間のアクセス制御を柔軟に設計できます。
pub(crate): クレート内での公開
pub(crate)
を使用すると、同じクレート内のすべてのモジュールからフィールドやメソッドにアクセスできます。ただし、クレートの外部からはアクセスできません。
使用例
以下はpub(crate)
を使用した例です:
mod module_a {
pub(crate) struct InternalStruct {
pub(crate) data: i32,
}
impl InternalStruct {
pub(crate) fn new(data: i32) -> InternalStruct {
InternalStruct { data }
}
}
}
mod module_b {
use crate::module_a::InternalStruct;
pub fn use_internal_struct() {
let instance = InternalStruct::new(42);
println!("Data: {}", instance.data); // クレート内からアクセス可能
}
}
この例では、InternalStruct
とそのメソッド、フィールドはクレート内のどのモジュールからもアクセス可能ですが、クレート外からはアクセスできません。
適用場面
- ライブラリ内部のデータを共有する場合:クレート全体で利用可能にするが、外部利用者には非公開としたい場合に最適です。
- 実装の詳細を隠す:APIとして公開する必要のない内部ロジックを安全に管理できます。
pub(super): 親モジュールに対する公開
pub(super)
を使用すると、直接の親モジュールに対してのみ公開されます。親モジュールを超えてアクセスすることはできません。
使用例
以下はpub(super)
を使用した例です:
mod module_a {
pub(super) struct ParentStruct {
pub(super) value: String,
}
impl ParentStruct {
pub(super) fn new(value: &str) -> ParentStruct {
ParentStruct {
value: value.to_string(),
}
}
}
mod module_b {
use super::ParentStruct;
pub fn access_parent_struct() {
let instance = ParentStruct::new("Hello");
println!("Value: {}", instance.value); // 親モジュールからアクセス可能
}
}
}
この例では、ParentStruct
はmodule_a
内でのみ利用可能です。module_a
を超えたアクセスは制限されます。
適用場面
- モジュール内の限定公開:親子モジュール間で共有する必要があるが、それ以外には公開したくない場合に便利です。
- 安全なモジュール設計:子モジュールからのみアクセス可能にすることで、モジュールの依存関係を明確化します。
pub(crate)とpub(super)の違い
修飾子 | アクセス範囲 | 使用例 |
---|---|---|
pub(crate) | 同一クレート内のすべてのモジュール | クレート全体で共有が必要なデータやロジック |
pub(super) | 親モジュール内のみ | 親モジュールに限定した共有が必要な場合 |
柔軟なアクセス制御の実現
これらの修飾子を使うことで、次のような柔軟な設計が可能になります:
- APIと内部ロジックの明確な分離:公開する部分と非公開部分を厳密に分けることができます。
- 依存関係の制御:アクセス範囲を必要最小限に抑えることで、モジュール間の依存関係を簡潔に保ちます。
- 安全性の向上:意図しない外部からの操作を防ぎ、コードの安定性を高めます。
これらの修飾子を活用することで、モジュール設計がより堅牢かつ保守性の高いものになります。次に、フィールドのプライバシーとコードの安全性との関連性について詳しく解説します。
フィールドのプライバシーと安全性
Rustにおけるフィールドのプライバシー設定は、コードの安全性を確保するための重要な手段です。適切なプライバシー設定を行うことで、予期しないエラーやセキュリティ上のリスクを防ぎ、安定したシステムを構築できます。
プライバシー設定と安全性の関係
1. 外部からの直接操作を防ぐ
非公開(private)フィールドを使用することで、モジュール外部からの直接的な操作を防ぎます。これにより、フィールドが意図しない値に変更されるリスクを軽減できます。
pub struct Account {
balance: f64, // 非公開フィールド
}
impl Account {
pub fn new() -> Account {
Account { balance: 0.0 }
}
pub fn deposit(&mut self, amount: f64) {
if amount > 0.0 {
self.balance += amount;
}
}
pub fn get_balance(&self) -> f64 {
self.balance
}
}
上記の例では、balance
フィールドが非公開になっているため、直接変更できず、不正な操作が防止されます。
2. モジュール設計のカプセル化
プライバシー設定は、データやロジックのカプセル化を実現します。内部のデータ構造や実装を隠すことで、モジュールの外部に対する影響を最小限に抑え、変更にも柔軟に対応できます。
mod data {
pub struct DataManager {
private_data: Vec<i32>, // 非公開
}
impl DataManager {
pub fn new() -> DataManager {
DataManager {
private_data: Vec::new(),
}
}
pub fn add_data(&mut self, value: i32) {
self.private_data.push(value);
}
pub fn get_data(&self) -> &[i32] {
&self.private_data // 非公開データを参照で提供
}
}
}
この例では、private_data
が外部に隠されているため、直接的な操作を回避できます。
公開範囲の限定による安全性の向上
1. 必要最小限の公開
pub(crate)
やpub(super)
を使用して、データの公開範囲を限定することで、意図しないモジュール間の依存を防ぎます。
mod library {
pub(crate) struct Book {
pub(crate) title: String, // クレート内でのみ公開
private_notes: String, // 完全非公開
}
impl Book {
pub(crate) fn new(title: &str, notes: &str) -> Book {
Book {
title: title.to_string(),
private_notes: notes.to_string(),
}
}
}
}
2. 安全なデータ共有
フィールドを直接公開せず、GetterやSetterメソッドを通じてデータを管理することで、アクセスの安全性を確保します。
プライバシー設定とセキュリティ
Rustでは、以下の理由からフィールドのプライバシー設定がセキュリティ上重要です:
- データの整合性を維持:非公開フィールドは、予期しない値で更新されるリスクを回避します。
- 攻撃対象を減少:公開範囲が狭いほど、攻撃者が操作可能なエントリーポイントが減少します。
- バグの発見が容易:アクセス経路が明確であるため、バグの特定が容易になります。
まとめ
フィールドのプライバシー設定は、コードの安全性を確保する基本です。適切に設定することで、以下を実現できます:
- モジュールのカプセル化と安全なデータ管理
- 公開範囲を限定することによるセキュリティ強化
- データ操作の制御による予期しないエラーの防止
次に、モジュール境界を超えたアクセスを実現する方法を解説します。
モジュール境界を超えたアクセスの実現方法
Rustでは、モジュール間のデータ共有を適切に管理するために、非公開フィールドへの直接アクセスを避け、間接的な方法でモジュール外部からフィールドを操作します。この実現には主にGetterやSetter、そして特定のメソッドを活用する手法があります。
GetterとSetterの役割
Getter
Getterは、非公開フィールドの値をモジュール外部に安全に提供するために使用されます。値の読み取りのみを許可することで、不正な変更を防ぎます。
Setter
Setterは、非公開フィールドの値を制御された方法で変更するために使用されます。値の検証や更新条件を設定することで、意図しない変更を回避できます。
Getterを用いたアクセス
以下の例は、非公開フィールドbalance
をGetterを通じて公開する方法です。
pub struct Account {
balance: f64, // 非公開フィールド
}
impl Account {
pub fn new(initial_balance: f64) -> Account {
Account { balance: initial_balance }
}
pub fn get_balance(&self) -> f64 {
self.balance // 値を提供
}
}
使用例:
fn main() {
let account = Account::new(100.0);
println!("Current Balance: {}", account.get_balance()); // Getterを使用
}
この方法では、balance
の値は外部から変更できませんが、読み取りは安全に行えます。
Setterを用いたアクセス
以下の例は、Setterを使用してbalance
の値を更新する方法です。
pub struct Account {
balance: f64, // 非公開フィールド
}
impl Account {
pub fn new() -> Account {
Account { balance: 0.0 }
}
pub fn deposit(&mut self, amount: f64) {
if amount > 0.0 {
self.balance += amount; // 条件を満たす場合のみ更新
}
}
pub fn withdraw(&mut self, amount: f64) -> bool {
if amount > 0.0 && amount <= self.balance {
self.balance -= amount;
true
} else {
false // 更新失敗
}
}
}
使用例:
fn main() {
let mut account = Account::new();
account.deposit(50.0);
println!("After Deposit: {}", account.get_balance());
if account.withdraw(20.0) {
println!("Withdrawal Successful: {}", account.get_balance());
} else {
println!("Withdrawal Failed");
}
}
モジュール間での安全なフィールド操作
GetterとSetterを活用することで、モジュール境界を超えたフィールドの操作が可能になります。以下は、モジュール間でアクセスを管理する方法の例です:
mod library {
pub struct Book {
title: String, // 非公開
pub(crate) author: String, // クレート内で公開
}
impl Book {
pub fn new(title: &str, author: &str) -> Book {
Book {
title: title.to_string(),
author: author.to_string(),
}
}
pub fn get_title(&self) -> &str {
&self.title // Getterを使用
}
}
}
mod consumer {
use crate::library::Book;
pub fn display_book_info() {
let book = Book::new("Rust Programming", "Author Name");
println!("Title: {}", book.get_title()); // Getter経由でアクセス
}
}
応用例: 高度な制御
公開範囲をさらに制御するため、条件付きのGetterやSetterを作成できます。以下は、特定の権限が必要なアクセスを実現する例です:
pub struct SecureData {
data: String,
}
impl SecureData {
pub fn new(data: &str) -> SecureData {
SecureData {
data: data.to_string(),
}
}
pub fn access_data(&self, auth: bool) -> Option<&str> {
if auth {
Some(&self.data) // 認証が成功した場合のみ提供
} else {
None // 認証失敗
}
}
}
使用例:
fn main() {
let secure = SecureData::new("Secret Info");
if let Some(data) = secure.access_data(true) {
println!("Access Granted: {}", data);
} else {
println!("Access Denied");
}
}
まとめ
- GetterとSetter:非公開フィールドへの安全なアクセスを実現。
- 条件付きアクセス:認証や検証を通じてアクセスを制御。
- 応用可能性:柔軟なアクセス制御により、モジュール間のデータ共有が明確化。
これにより、モジュール外部からのフィールド操作を安全に実現できます。次に、プライバシー設定における典型的なミスとその対策を解説します。
プライバシーに関する典型的なミスとその対策
Rustでは、フィールドやメソッドの公開範囲を適切に設定しないと、予期しないバグやセキュリティ上のリスクにつながることがあります。ここでは、プライバシー設定における典型的なミスとその対策について解説します。
典型的なミス
1. 必要以上にフィールドを公開してしまう
すべてのフィールドをpub
に設定してしまうことで、モジュール外部からの不正アクセスや意図しない変更が可能になります。
例:
pub struct User {
pub username: String,
pub password: String, // パスワードが公開されている!
}
問題点:
- セキュリティリスク:重要な情報(例:パスワード)が直接アクセス可能。
- データ整合性の欠如:外部で意図しない値に変更される可能性。
対策:
非公開に設定し、必要に応じてGetterやSetterを提供します。
pub struct User {
username: String,
password: String, // 非公開フィールド
}
impl User {
pub fn new(username: &str, password: &str) -> User {
User {
username: username.to_string(),
password: password.to_string(),
}
}
pub fn check_password(&self, input: &str) -> bool {
self.password == input // パスワードを直接公開せず比較
}
}
2. `pub(crate)`や`pub(super)`の誤用
公開範囲を適切に指定しないと、意図しないモジュールやクレート全体にデータが公開される場合があります。
例:
pub(crate) struct InternalConfig {
pub(crate) api_key: String, // クレート内全体に公開
}
問題点:
- クレート内のすべてのモジュールからアクセス可能になり、セキュリティリスクが増加。
対策:
必要な範囲に限定して公開し、慎重に設計します。
mod config {
pub(super) struct InternalConfig { // 親モジュールに限定
api_key: String,
}
impl InternalConfig {
pub fn new(api_key: &str) -> InternalConfig {
InternalConfig {
api_key: api_key.to_string(),
}
}
pub fn get_api_key(&self) -> &str {
&self.api_key // 安全にアクセスを提供
}
}
}
3. GetterやSetterの実装漏れ
非公開フィールドにアクセスするためのメソッドを用意せず、外部からの操作ができなくなるケースがあります。
例:
pub struct Data {
value: i32, // 非公開
}
問題点:
- 非公開フィールドにアクセスできないため、外部から値を取得したり更新したりすることが不可能。
対策:
必要なGetterやSetterを実装します。
pub struct Data {
value: i32, // 非公開
}
impl Data {
pub fn new(value: i32) -> Data {
Data { value }
}
pub fn get_value(&self) -> i32 {
self.value
}
pub fn set_value(&mut self, value: i32) {
self.value = value;
}
}
その他のミス
1. 公開範囲の変更がモジュールに与える影響を見落とす
プライバシー設定を変更した場合、他のモジュールやクレートでの使用方法に影響を及ぼす可能性があります。
対策:
- プライバシー設定を変更する際は、依存するコードをすべて確認します。
- 変更が大規模な場合は、影響範囲を明確にしてテストを行います。
2. 複雑な公開範囲の設定でメンテナンス性を低下させる
多くのpub(crate)
やpub(super)
を組み合わせると、コードの読みやすさやメンテナンス性が低下します。
対策:
- 公開範囲を最小限に保つシンプルな設計を心掛ける。
- モジュールやクレートの設計を見直し、冗長な公開設定を減らす。
まとめ
- 公開範囲を最小限に:必要以上に公開しない。
- Getter/Setterを活用:安全なアクセス方法を提供する。
- 設計をシンプルに:メンテナンス性と可読性を向上させる。
これらの対策を実践することで、プライバシー設定のミスを防ぎ、安全で保守性の高いコードを構築できます。次に、プライバシー設定を確認するための演習問題を紹介します。
プライバシー設定を確認するための演習問題
Rustにおけるプライバシー設定をより深く理解するために、以下の演習問題に挑戦してみましょう。これらの問題を通じて、pub
、pub(crate)
、pub(super)
の使用方法やGetter/Setterの実装について学べます。
演習1: 非公開フィールドにアクセスするGetterを実装する
次のコードには、非公開フィールドsecret
があります。このフィールドを外部から読み取るためのGetterを実装してください。
pub struct HiddenData {
secret: String,
}
impl HiddenData {
pub fn new(secret: &str) -> HiddenData {
HiddenData {
secret: secret.to_string(),
}
}
// ここにGetterを実装してください
}
期待する出力例:
let data = HiddenData::new("Hidden Information");
println!("{}", data.get_secret()); // "Hidden Information"
演習2: `pub(crate)`の使用
以下のコードはConfig
構造体を定義しています。この構造体をモジュールsettings
内で作成し、同じクレート内の別モジュールから使用できるように設定してください。ただし、クレート外からはアクセスできないようにしてください。
mod settings {
pub struct Config {
key: String,
}
impl Config {
pub fn new(key: &str) -> Config {
Config {
key: key.to_string(),
}
}
}
}
// 別モジュールからConfigを使用してください。
fn main() {
// 設定されたアクセス修飾子で動作するか確認してください。
}
演習3: Setterで値を検証して更新する
以下のAccount
構造体に対して、balance
フィールドを更新するためのSetterを作成してください。ただし、更新される値が負の場合は更新を拒否するようにしてください。
pub struct Account {
balance: f64,
}
impl Account {
pub fn new() -> Account {
Account { balance: 0.0 }
}
// ここにSetterを実装してください
}
期待する動作:
- 正の値の場合のみ
balance
が更新される。 - 負の値の場合はエラーや更新の拒否を通知する。
let mut account = Account::new();
account.set_balance(100.0); // 正常に更新
println!("Balance: {}", account.get_balance()); // 100.0
account.set_balance(-50.0); // 更新を拒否
println!("Balance: {}", account.get_balance()); // 100.0
演習4: モジュール間のアクセス制御
以下のコードにpub(super)
を使用して、モジュールlibrary
内でのみアクセス可能なBook
構造体を実装してください。library
外部からはアクセスを制限します。
mod library {
pub(super) struct Book {
title: String,
}
impl Book {
pub fn new(title: &str) -> Book {
Book {
title: title.to_string(),
}
}
pub fn get_title(&self) -> &str {
&self.title
}
}
}
// library外部からアクセスしてみてください。
fn main() {
// 本のタイトルを取得しようとするとエラーが発生することを確認してください。
}
演習5: プライバシー設定の誤りを修正する
以下のコードには、プライバシー設定の問題があります。この問題を修正して、適切なアクセス制御を実現してください。
pub struct User {
pub username: String,
pub password: String, // 公開されている
}
impl User {
pub fn new(username: &str, password: &str) -> User {
User {
username: username.to_string(),
password: password.to_string(),
}
}
pub fn check_password(&self, input: &str) -> bool {
self.password == input
}
}
修正後の要件:
password
フィールドは非公開に設定。- 必要に応じて、パスワードを比較する関数だけを公開する。
まとめ
これらの演習問題に取り組むことで、プライバシー設定の理解が深まります。特に、非公開フィールドを操作する際のGetter/Setterの実装や、公開範囲の調整が重要なスキルとして身につきます。最後のセクションでは、本記事の内容をまとめます。
まとめ
本記事では、Rustにおけるフィールドのプライバシー設定とモジュール間の関係性について解説しました。非公開フィールドを安全に操作するためのGetterやSetterの実装方法、pub(crate)
やpub(super)
を活用した柔軟なアクセス制御、プライバシー設定で陥りがちなミスとその対策について具体的な例を交えて説明しました。
プライバシー設定を適切に管理することで、以下のポイントを実現できます:
- モジュール間のデータ共有を安全かつ明確に設計する。
- データ整合性を保ち、セキュリティリスクを最小限に抑える。
- 必要最小限の公開で、可読性と保守性を向上させる。
これらの知識を基に、Rustのプライバシー設定を活用して、より安全で堅牢なコードを構築してください。
コメント