Defining and building structs
A struct groups related values under one name, with a named, typed field for each. It is Rust's answer to a class's data — but with no inheritance, and with behaviour added separately in impl blocks (next lessons). Struct names are PascalCase, fields are snake_case.
struct User {
name: String,
email: String,
active: bool,
logins: u32,
}
fn new_user(name: String, email: String) -> User {
User {
name, // field init shorthand: same as name: name
email,
active: true,
logins: 0,
}
}
fn main() {
let mut ada = new_user(String::from("ada"), String::from("[email protected]"));
ada.logins += 1; // the whole instance is mut, never one field
println!("{} <{}> active={} logins={}", ada.name, ada.email, ada.active, ada.logins);
// struct update syntax: take the rest of the fields from another value
let bot = User {
name: String::from("deploy-bot"),
email: String::from("[email protected]"),
..ada
};
println!("{} active={} logins={}", bot.name, bot.active, bot.logins);
println!("{} still usable", ada.name);
}ada <[email protected]> active=true logins=1
deploy-bot active=true logins=1
ada still usable..ada copied only active and logins, which are Copy. Had it filled in a String field, that field would have moved out of ada and ada.name could still be used but ada as a whole could not.
E0063: every field must be given a value
struct User {
name: String,
email: String,
active: bool,
}
fn main() {
let u = User {
name: String::from("ada"),
email: String::from("[email protected]"),
};
println!("{}", u.name);
}error[E0063]: missing field `active` in initializer of `User`
--> main.rs:8:13
|
8 | let u = User {
| ^^^^ missing `active`Rust has no default or null field values. A struct is either fully initialised or it does not exist, so reading a field can never give you garbage.
Give every field a value, or write a constructor function (an associated function, below) that fills in the defaults once. #[derive(Default)] plus ..Default::default() is the other common answer.
struct User {
name: String,
email: String,
active: bool,
}
fn main() {
let u = User {
name: String::from("ada"),
email: String::from("[email protected]"),
active: true,
};
println!("{}", u.name);
}