Rust構造体の変数を初期化するためのより速い/より短い方法はありますか?


102

次の例では、フィールドの宣言で、構造体の各フィールドに値を割り当てることをお勧めします。または、フィールドに値を割り当てるために、フィールドごとに1つの追加ステートメントを効果的に使用します。私ができることは、構造体がインスタンス化されるときにデフォルト値を割り当てることだけです。

これを行うためのより簡潔な方法はありますか?

struct cParams {
    iInsertMax: i64,
    iUpdateMax: i64,
    iDeleteMax: i64,
    iInstanceMax: i64,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

impl cParams {
    fn new() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}

回答:


161

Defaultトレイトを実装することで、構造体のデフォルト値を提供できます。defaultこの関数は、現在のようになりますnew機能:

impl Default for cParams {
    fn default() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}

次に、デフォルト以外の値のみを指定して、構造体をインスタンス化できます。

let p = cParams { iInsertMax: 10, ..Default::default() };

データ構造に若干の変更を加えることで、自動的に派生したデフォルトの実装を利用できます。#[derive(Default)]データ構造で使用する場合、コンパイラーは自動的にデフォルト関数を作成し、各フィールドにデフォルト値を入力します。デフォルトのブール値はfalse、デフォルトの整数値は0です。

整数のフィールドをデフォルトで-1にしたいので、整数のデフォルト値が0であると、ここで問題になります。-1のデフォルト値を実装する新しいタイプを定義i64して、構造体の代わりにそれを使用できます。(私はテストしていませんが、動作するはずです)。

ただし、データ構造を少し変更してのOption<i64>代わりに使用することをお勧めしますi64。コードのコンテキストはわかりませんが、特別な値-1を使用して「無限」または「最大値がない」という特別な意味を表しているようです。RustではOption、オプションで存在する値を表すためにを使用します。-1ハックの必要はありません。オプションはどちらか、NoneまたはSome(x)xはi64ここにあります。-1が唯一の負の値である場合、符号なし整数になることもあります。デフォルトOption値はNoneなので、提案された変更により、コードは次のようになります。

#[derive(Default)]
struct cParams {
    iInsertMax: Option<u64>,
    iUpdateMax: Option<u64>,
    iDeleteMax: Option<u64>,
    iInstanceMax: Option<u64>,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

let p = cParams { iInsertMax: Some(10), ..Default::default() };

1
ありがとう、すぐに読みましたが、理解を深めるために読み直します。一部の言語が使用する「自然な」デフォルトは、ゼロ、偽、「」などが適していると思います。私が解決する小さな「問題」よりも広い意味があることを理解しています。例を述べる能力 "iVal:i64 = 0"は、私のより広いニーズを解決しますが、それは起こらないと思います。「#[deriving(Default)]」は私の欲求のほとんどを解決するはずです。テストプログラムで-1を使用した理由はわかりませんが、必要ありません(履歴)。フィールドが定義されているその場で値を割り当てることができれば、非常に便利です(IMHO)。
Brian Oh

9
@BrianOh、接線的に、「構造体フィールドのデフォルト値」(つまりのようなものstruct Foo { val: i64 = 0 })が提案されており、それ以降のバージョンで表示される可能性があります。
2013年

それがIMO-"struct foo {...."を実装しているとよいでしょう。私はあなたの提案に従って、私の質問に書かれている構造体をデフォルトで使用して変更を加えました。それは確かに私によく合い、はるかに簡潔です。構文に慣れていないので、私が抱えていた小さな問題の1つは、すべてのデフォルトの構文を知らないことでした。IE:「= cParams {iInsertMax:10、..Default :: default()};」を使用しましたが、実際には「iInstanceMax」もデフォルトにしたいと思っています。IMO "#[deriving(Default)]"​​が構造体の一部であることが望ましいですが、コンパイラーの方がより適していると思います。
ブライアン・オー

2
本当にありがとうございました。私見デフォルトはデフォルトでなければなりません。IE。Default:defaultなどを指定する必要はないと思います。また、フィールドには、それらが定義されている値を割り当てることができる必要があると思います。それは私の単純な見方からです。Rustは安全に設計されていること、そして私よりもはるかに広い見方があることに気づきました。言語(または少なくとも私)を学んでいるとき、現在の実装は少し面倒です。Rustは単純な言語の私見ではありません。少なくとも私にとっては、Rustを単純化するために実行可能なことが多ければ多いほど良いでしょう。
ブライアン・オー

2
Default構造体を実装する場合、すべてのフィールドのデフォルトを定義する必要がありますか?
マシュースティーブンソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.