2016-12-12 16 views
8

錆は、既存の構造体を使用でき、そのメンバの一部をオーバーライドするだけの便利な機能を備えています。例えば、以下の構造体一部のメンバーだけが別の構造体の値を使用できる構造体を宣言するにはどうすればいいですか?

struct SomeTool { 
    pub unique_id: String, 
    pub poll: Option<fn(&Context) -> bool>, 
    pub exec: Option<fn(&mut Context) -> ToolResult>, 
    pub modal: Option<fn(&mut Context) -> ToolResult>, 
    pub ui: Option<fn(&mut UIPanel)>, 
} 

の値は、構造体のインスタンス(例えばSomeTool::default())に渡すことで初期化することができます。

new_tool = SomeTool { 
    unique_id: "tool.foobar".to_string(), 
    exec: Some(foobar_exec) 
    .. SomeTool::default() 
}; 

私は明示的にリストアップしなくてもSomeToolを宣言することができるようにしたいですすべてのコールバック(将来、新しいコールバックを追加すると、コードベース全体にNoneが追加される可能性があります)。

これはうまくいきましたが、私は誤って他の初期化のためにunique_idを残してしまい、defaultにあるものを使用していました。

一部のメンバーをオーバーライドできますが、他のメンバーはオーバーライドできない構造体を記述する方法はありますか?

実世界のユースケースには、これよりも多くのメンバーが存在する(事故の可能性が高くなる)ことに注意してください。

答えて

8

unique_idは一意であると想定されているため、Defaultコンストラクタを使用しないでください。しかし、仮説UniqueIdタイプからDefaultインプリを削除すると、のDefaultを得ることができなくなります。

現行の解決策は、値を必要としないすべてのフィールドをサブ構造体に移動し、にDefaultを実装しないことです。次のようにこのようにあなたはSomeToolを使用することができるだろう:錆がで基本式であるためにあなたが同じフィールドを持つ2つの構造体を持つことができます将来的になるかもしれないという仮定の機能があります

new_tool = SomeTool { 
    unique_id: "tool.foobar".to_string(), 
    callbacks: Callbacks { 
     exec: Some(foobar_exec), 
     .. Callbacks::default() 
    } 
}; 

構造体式。この機能を使用すると、サブ構造体を使用して、サブ構造体とSomeToolに共通するフィールドをすべて初期化できますが、それ以上のフィールドは初期化できません。

関連する問題