問題の歴史:
Rustは明示的な初期化の哲学を守っています。一部の標準コレクションや汎用型では、"デフォルト"値を持つことがしばしば必要です。しかし、複雑な構造については、引数なしでどのように作成するかがあいまいであることが少なくありません。この目的のために、標準コンストラクタを定義するトレイトDefaultが導入されました。
問題:
汎用コンテナやアルゴリズムを記述するためには、時にはデフォルト値が期待されることがあり(例えば、Option::unwrap_or_defaultやVec::resizeなど)、引数を渡さずにインスタンスを生成するメカニズムが必要です。しかし、すべての型がそのようなコンストラクタに適しているわけではなく、時にはデフォルト値が明白でなかったり危険である可能性もあります。
解決策:
default()メソッドを提供します(通常は"空"、ゼロ初期化されたもの、または前提条件を満たすもの)。コード例:
#[derive(Default, Debug)] struct Config { retries: u32, verbose: bool, } fn main() { let cfg = Config::default(); println!("{:?}", cfg); }
重要な特徴:
Option<T>に対してT: Defaultの場合、Default::defaultは強制的に呼び出されますか?
いいえ、OptionalはTのためにdefaultを自動的には呼び出しません;unwrap_or_defaultは明示的に呼び出されます。
デフォルト値を持つパラメータを構造体のコンストラクタ内でDefaultトレイトを介して指定できますか?
いいえ、Defaultは構造体全体を生成し、個々のフィールドのデフォルトを通常のコンストラクタの構文で上書きすることはできません。
構造体のフィールドがDefaultを実装していない場合、derive(Default)は失敗しますか?
はい、derive(Default)は構造体内のすべてのフィールドがDefaultを実装している場合にのみ機能します。
サーバーポートが0(無効なデフォルト値)でConfig c Default。プログラムが予期しないポートで起動します。
長所:
短所:
安全で合意された値(retries=3、verbose=false)を持つ設定構造のDefault。
長所:
短所: