This pattern is fairly good but doesn't support required arguments.
struct User {
id: Id,
email: EMail,
name: String = String::new(),
age: u16 = 0,
}
let user = User { id, email, .. }; // valid
let user = User { id, .. }; // complain about email missing
It would leverage `const` expressions, so it would desugar effectively to the same as if you had written: const DEFAULT_USER_NAME: String = String::new();
const DEFAULT_USER_AGE: u16 = 0;
struct User {
id: Id,
email: EMail,
name: String,
age: u16,
}
let user = User { id, email, name: DEFAULT_USER_NAME, age: DEFAULT_USER_AGE };
The above assumes that String::new will be const at some point (it can be).If this ever lands, then there will be less need to write Builder traits by hand.
Also, at some point the free-standing `default()` function that calls `Default::default()` will land, making it that much shorter to write (without any new features like I'm proposing).
It has been const since Rust 1.39 (https://doc.rust-lang.org/std/string/struct.String.html#meth...)
Or can consts have multiple owners since they're immutable and have a static lifetime? Is this just the first case of a non-Copy being const, so the question has never come up before?
Statics, in contrast, have a storage location and a static lifetime.
Compare:
const CONST_STRING: String = String::new();
static STATIC_STRING: String = String::new();
fn main() {
let x: String = CONST_STRING; // fine
let y: String = STATIC_STRING; // error: cannot move out of static item
} new(required_arg_1, required_arg_2, Options { foo: "bar", ..Default::default() })
or Options { foo: "bar", ..Default::default() }).build(required_arg_1, required_arg_2)