2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rustのパブリックなコンストラクタメソッドを持つ構造体とは

Posted at

はじめに

私はオブジェクト指向言語の経験者なのですが、
オブジェクト指向でいうところのクラスはRustの構造体という記事を見てから積極的に構造体が使えるようになってきました。

コーディングを進める中で、モジュールの構造体のフィールドをPrivateにしたい場合が出てきました。
しかし外部から利用するにはPublicにせざるを得ません。
解決方法は、日本語ドキュメントにありました。(おわり)

この記事は、基本的に以下ページに書いてあることのままですが、ドキュメントを一読しただけでは利用場面が想像しづらかったので整理しました。

PublicとPrivateを考慮できていないパターン

まずは、コンパイルエラーになる書き方から見ていきます。
CatDataはPublicですが、name, returnCodeはPrivateなのでコンパイルエラーになります。

lib
// 構造体
pub struct CatData {
    name: String,
    return_code: String
}
main
// 何らかの処理
let name = "Tama";
let tama_rescode = getCatData(name);

// インスタンス化
let cat = CatData {
    name: name.to_string(), // field `name` of struct `xxx::CatData` is private
  return_code: tama_rescode // field `return_code` of struct `xxx::CatData` is private
};

// 利用
println!("returnCode: {}", cat.return_code); // field `return_code` of struct `xxx::CatData` is private

解決方法①:Publicなフィールドを持つPublicな構造体にする

フィールドの前にpubをつけるだけでコンパイルがとおります。

lib
// 構造体
pub struct CatData {
    pub name: String,
    pub return_code: String
}

問題は、フィールドを公開したくない場合です。
例の場合、nameは外部参照される予定がありませんが、pubにせざるを得ない状況です。

解決方法②:PrivateなフィールドとPublicなコンストラクタメソッドを持つ構造体にする

lib
// 構造体
pub struct CatData {
    kind: String, // 外部から更新されないフィールドも使える
    name: String,
    return_code: String
}
// 構造体CatDataのメソッド(メソッドとはオブジェクトに付属した関数)を定義
impl CatData {
    // Publicなコンストラクタメソッド
    pub fn new(name: &str, response_code: String) -> CatData {
        CatData {
            kind: "Animal".to_string(),
            name: name.to_string(),
            response_code: response_code
        }
    }
    
    // response_codeを外部から利用するためのPublicメソッド
    pub fn get_code(&self) -> String {
        self.response_code.clone()
    }
main
// 何らかの処理
let name = "Tama";
let tama_rescode = getCatData(name);

// インスタンス化
let cat = CatData::new(name, tama_rescode);

// 利用
println!("returnCode: {}", cat.get_code());

おわりに

ありがとうございました。
ほぼオブジェクト指向の設計で進められているのですが、Rustにクラスがないことの意味をちゃんと考えたほうがいいかもしれません。

なおWikipediaには、マルチパラダイムプログラミング言語と書かれていました。

Rustはマルチパラダイムプログラミング言語であり、手続き型プログラミング、オブジェクト指向プログラミング、関数型プログラミングなどの実装手法をサポートしている。

すごい。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?