演習: ビルダー型
この例では、すべてのデータを持つ複雑なデータ型を実装します。「ビルダー パターン」で便利な関数を使用して、新しい値を 1 つずつ構築できるようにします。
抜けている部分を記入してください。
#[derive(Debug)] enum Language { Rust, Java, Perl, } #[derive(Clone, Debug)] struct Dependency { name: String, version_expression: String, } /// ソフトウェア パッケージの表現。 #[derive(Debug)] struct Package { name: String, version: String, authors: Vec<String>, dependencies: Vec<Dependency>, language: Option<Language>, } impl Package { /// このパッケージの表現を依存関係として返し、 /// 他のパッケージのビルドに使用します。 fn as_dependency(&self) -> Dependency { todo!("1") } } /// パッケージのビルダー。`build()` を使用して `Package` 自体を作成します。 struct PackageBuilder(Package); impl PackageBuilder { fn new(name: impl Into<String>) -> Self { todo!("2") } /// パッケージのバージョンを設定します。 fn version(mut self, version: impl Into<String>) -> Self { self.0.version = version.into(); self } /// パッケージ作成者を設定します。 fn authors(mut self, authors: Vec<String>) -> Self { todo!("3") } /// 依存関係を追加します。 fn dependency(mut self, dependency: Dependency) -> Self { todo!("4") } /// 言語を設定します。設定しない場合、言語はデフォルトで None になります。 fn language(mut self, language: Language) -> Self { todo!("5") } fn build(self) -> Package { self.0 } } fn main() { let base64 = PackageBuilder::new("base64").version("0.13").build(); println!("base64: {base64:?}"); let log = PackageBuilder::new("log").version("0.4").language(Language::Rust).build(); println!("log: {log:?}"); let serde = PackageBuilder::new("serde") .authors(vec!["djmitche".into()]) .version(String::from("4.0")) .dependency(base64.as_dependency()) .dependency(log.as_dependency()) .build(); println!("serde: {serde:?}"); }