← Back to Rust Course | Chapter 7: Structs | Lesson 6 of 7

Struct Update Syntax

Struct update syntax lets you build a new struct that's mostly a copy of an old one, but with a couple of fields swapped out.

Basic Struct Update Syntax

Struct update syntax lets you create a new instance based on an existing one, explicitly overriding only the fields you want to change and copying the rest with ..base.

Example: Basic Struct Update Syntax

markup
#[derive(Debug)]
struct Config {
    width: u32,
    height: u32,
    fullscreen: bool,
}

fn main() {
    let default_config = Config { width: 800, height: 600, fullscreen: false };
    let custom = Config { fullscreen: true, ..default_config };
    println!("{:?}", custom);
}

Moving Non-Copy Fields

If the base struct contains non-Copy fields like String that are not overridden, those fields are moved into the new instance, making the original struct partially unusable afterward.

Example: Moving Non-Copy Fields

markup
#[derive(Debug)]
struct Profile {
    username: String,
    active: bool,
}

fn main() {
    let base = Profile { username: String::from("guest"), active: false };
    let updated = Profile { active: true, ..base };
    println!("{:?}", updated);
}

..base Must Come Last

The ..base syntax must always appear as the final item in a struct literal, after every explicitly assigned field, since it fills in whatever remains.

Example: ..base Must Come Last

markup
#[derive(Debug)]
struct Point3D {
    x: i32,
    y: i32,
    z: i32,
}

fn main() {
    let origin = Point3D { x: 0, y: 0, z: 0 };
    let shifted = Point3D { x: 5, ..origin };
    println!("{:?}", shifted);
}

Combining With Copy Structs

When the base struct's fields are all Copy types, using struct update syntax leaves the original instance fully usable afterward, since nothing was moved out of it.

Example: Combining With Copy Structs

markup
#[derive(Debug, Clone, Copy)]
struct Settings {
    volume: u8,
    brightness: u8,
}

fn main() {
    let defaults = Settings { volume: 50, brightness: 70 };
    let louder = Settings { volume: 80, ..defaults };
    println!("defaults still usable: {:?}", defaults);
    println!("louder: {:?}", louder);
}
Common Mistakes
  1. Forgetting that struct update syntax ..other moves non-Copy fields out of other, potentially invalidating it afterward.
  2. Placing ..other before other field assignments -- it must come last in the struct literal.
  3. Assuming struct update syntax mutates the original struct in place, when it actually creates a brand new instance.
Chapter Summary
  • ..other_instance at the end of a struct literal fills in any remaining fields from an existing instance.
  • Only the fields not explicitly listed are copied or moved from the base instance.
  • If any moved (non-Copy) fields are taken from the base instance, that instance can no longer be used afterward.
  • This syntax is a concise way to create variations of a struct without repeating every field.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.