Step 3 of 6
Building structs with shorthand and update syntax
Building structs in functions is so common that Rust has two shortcuts for it.
Field init shorthand
When a variable has the same name as the field, write the name once: price_cents instead of price_cents: price_cents. This is the field init shorthand. Clippy flags the long form (redundant_field_names), so in real code you'll see the short one everywhere.
Struct update syntax
..other at the end of an instance means "every field I didn't list comes from other". This is struct update syntax, handy for "the same, but with these changes":
struct Settings {
player_name: String,
volume: u8,
music: bool,
difficulty: u8,
}
fn default_settings(player_name: String) -> Settings {
Settings {
player_name,
volume: 70,
music: true,
difficulty: 2,
}
}
fn main() {
let base = default_settings(String::from("Ferris"));
let hard = Settings {
difficulty: 5,
music: false,
..base
};
println!("{} plays at difficulty {}", hard.player_name, hard.difficulty);
println!("volume {}, music {}", hard.volume, hard.music);
}
Ferris plays at difficulty 5
volume 70, music false
- In
default_settings, the parameter is calledplayer_name, so the field is filled with justplayer_name,. hardlists two fields and takes the rest (player_name,volume) frombase...basemust come last, with no comma after it.
The update syntax moves
..base works like assignment: Copy fields (numbers, bool) are copied, but a String field is moved out of base. After that line, base.player_name is gone, while base.volume is still fine:
struct Player {
name: String,
score: u32,
}
fn main() {
let a = Player { name: String::from("Ferris"), score: 10 };
let b = Player { score: 99, ..a };
println!("{} {}", b.name, b.score);
println!("{}", a.name);
}
error[E0382]: borrow of moved value: `a.name`
If you still need a, give the moved fields explicitly (name: a.name.clone()), or just don't use a afterwards. Often the struct you update from is a temporary that's thrown away anyway.
Your task
Write fn new_item(name: &str, price_cents: u32) -> Item that returns an Item with that name and price, and a quantity of 0. Use the field init shorthand for price_cents.
Challenge 2
Write fn with_price(item: Item, price_cents: u32) -> Item. It returns the same item with a new price. Use struct update syntax (..item) for the fields that stay the same, and the shorthand for price_cents.
Challenge 3
Write two functions for a game:
fn new_character(name: String, class: String) -> Character: level 1 and 100 hp. Use the shorthand fornameandclass.fn promoted(c: Character) -> Character: one level higher and 20 more hp, with the same name and class. Use struct update syntax.
Previous: Changing structs and passing them around Next: Printing structs with Debug