5 ms·
As very early rustacean, why using that java-esque pattern when there’s that awesome Defaults derivable trait?
by yuchi 8y ago
As very early rustacean, why using that java-esque pattern when there’s that awesome Defaults derivable trait?
- honkycat 8y agoI had the same thought. This seems very OO and I wonder if it is idiomatic rust
- tomsmeding 8y agoFor anyone else who's confused how this presents an alternative to the builder pattern in the post: Rust's std::default::Default trait can be implemented for any struct (also automatically derived if you just want the members' standard default values), and then an instance of the struct can be created with the following syntax: [1] let instance = YourStruct { foo: 42, ..Default::default() }; where 'foo', and possibly more fields, are the ones you want to override from the default. The rest gets taken from the Default trait specialisation. Tangential: in Haskell, record types allow a similar sort of trick. If you have a data type like the following: data D = MakeD { a :: Int, b :: Float } and have a instance of that data type with your default values: defaultD = MakeD { a = 42, b = 3.14 } then you can create another instance of D by selectively overriding stuff from the already existing instance using similar syntax: someInstance = defaultD { a = 100 } which is equal to MakeD { a = 100, b = 3.14 }. [1]: adapted from https://doc.rust-lang.org/std/default/trait.Default.html https://doc.rust-lang.org/std/default/trait.Default.html
- ungzd 8y agoFor this example, builder pattern is definitely overkill, but builders can be still useful for more complex cases. Even for simple structs, sometimes you don't want to expose constructor, for example to add additional checks ("smart constructors" in Haskell jargon).
- killercup 8y agoThe simple builder pattern often looks like a lot of boilerplate, I agree. But you can easily crank the coolness of it up a notch by using one of these properties: - Hide the fields of your struct to not break your users when adding/changing fields - automatically convert data in your setters (accept a reference to a string even though you want to store a file system path) - use type parameters to conditionally set and validate values at compile time (by making your data type generic and implementing some setters so that they return a concrete value for that allowing you to write _different_ setters based on that type) - by using the session type pattern to disallow incorrect method calls at compile times (e.g. calling `set_content` after calling `submit`)
- Robin_Message 8y agoNot a rustacean, but the builder pattern lets you do things like validation and munging which just providing defaults does not do.