Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Rust Dictionary

  1. Home
  2. Rust Dictionary
  3. struct / Field Definitions

struct / Field Definitions

Since: Rust 1.0(2015)

A struct in Rust is a data type that groups multiple values together. There are three kinds: a regular struct with named fields, a tuple struct with unnamed fields, and a unit struct with no fields.

Syntax

// A regular struct (fields have names).
struct Point {
    x: f64,
    y: f64,
}

// A tuple struct (fields have no names).
struct Color(u8, u8, u8);

// A unit struct (no fields).
struct Marker;

// Creating instances.
let p = Point { x: 1.0, y: 2.5 };
let c = Color(255, 128, 0);
let m = Marker;

// Accessing fields.
println!("{}", p.x); // 1
println!("{}", c.0); // 255 (tuple structs use index access)

Struct Types

TypeDescription
struct Name { field: Type, ... }A regular struct with named fields.
struct Name(Type, Type, ...);A tuple struct with unnamed fields.
struct Name;A unit struct with no fields (used as trait markers, etc.).
let mut s = Struct { ... }Adding mut makes all fields mutable.
Field shorthandIf a variable name matches a field name, you can write { x, y } as shorthand.
struct S2 { .., ..s1 }Copy remaining fields from another instance (struct update syntax).

Sample Code

sample_struct_definition.rs
// A struct representing a sorcerer.
struct Sorcerer {
    name: String,
    email: String,
    grade: u32,
    active: bool,
}

// Tuple struct examples.
struct Point(f64, f64);
struct Meters(f64);

fn build_sorcerer(email: String, name: String) -> Sorcerer {
    Sorcerer {
        // Field shorthand: omit field name when variable name matches.
        email,
        name,
        grade: 1,
        active: true,
    }
}

fn main() {
    // Create an instance.
    let user1 = Sorcerer {
        name: String::from("Gojo Satoru"),
        email: String::from("gojo_satoru@wp-p.info"),
        grade: 1,
        active: true,
    };

    println!("Sorcerer: {}", user1.name);
    println!("Email: {}", user1.email);
    println!("Grade: {}", user1.grade);

    // Use mut to modify fields (the entire struct becomes mutable).
    let mut user2 = build_sorcerer(
        String::from("ryomen_sukuna@wp-p.info"),
        String::from("Ryomen Sukuna"),
    );
    user2.grade = 0;
    println!("Ryomen Sukuna's updated grade: {}", user2.grade);

    // Struct update syntax: create a new instance changing only some fields.
    let user3 = Sorcerer {
        email: String::from("itadori_yuji@wp-p.info"),
        name: String::from("Itadori Yuji"),
        ..user1 // Copy remaining fields from user1.
    };
    println!("user3 grade: {}", user3.grade); // 1 (copied from user1)
    println!("user3 active: {}", user3.active); // true

    // Using tuple structs.
    let p = Point(3.0, 4.0);
    let d = Meters(5.2);
    println!("Point: ({}, {})", p.0, p.1);
    println!("Distance: {} m", d.0);

    // Tuple structs support destructuring.
    let Point(x, y) = p;
    println!("x={}, y={}", x, y);
}

Compile with the following command:

rustc struct_definition.rs
./struct_definition
Sorcerer: Gojo Satoru
Email: gojo_satoru@wp-p.info
Grade: 1
Ryomen Sukuna's updated grade: 0
user3 grade: 1
user3 active: true
Point: (3, 4)
Distance: 5.2 m
x=3, y=4

Common Mistakes

Mistake 1: Ownership of a String field is moved by the struct update syntax

When a String field is copied via the update syntax (..other), String does not implement Copy, so ownership is moved to the new instance. After the move, that field on the original instance can no longer be accessed.

struct_def_mistake1.rs
#[derive(Debug)]
struct Sorcerer {
    name: String,
    grade: u32,
}

fn main() {
    let s1 = Sorcerer {
        name: String::from("Gojo Satoru"),
        grade: 1,
    };

    let s2 = Sorcerer {
        grade: 0,
        ..s1 // Ownership of s1.name is moved into s2.
    };

    println!("s2: {:?}", s2);
    // s1.name can no longer be used.
    // println!("{}", s1.name); // compile error

    // grade is Copy, so s1.grade is still accessible.
    println!("s1.grade: {}", s1.grade);
}

Compile with the following command:

rustc struct_def_mistake1.rs
./struct_def_mistake1
s2: Sorcerer { name: "Gojo Satoru", grade: 0 }
s1.grade: 1

To keep the original instance alive, call clone() before using the update syntax.

struct_def_fix1.rs
#[derive(Debug, Clone)]
struct Sorcerer {
    name: String,
    grade: u32,
}

fn main() {
    let s1 = Sorcerer {
        name: String::from("Gojo Satoru"),
        grade: 1,
    };

    let s2 = Sorcerer {
        grade: 0,
        ..s1.clone() // Clone s1 so that s1.name is copied, not moved.
    };

    // Both s1 and s2 are usable.
    println!("s1: {:?}", s1);
    println!("s2: {:?}", s2);
}

Compile with the following command:

rustc struct_def_fix1.rs
./struct_def_fix1
s1: Sorcerer { name: "Gojo Satoru", grade: 1 }
s2: Sorcerer { name: "Gojo Satoru", grade: 0 }

Mistake 2: Forgetting mut makes fields immutable

In Rust, modifying a struct instance requires declaring the variable as mut. You cannot make individual fields mutable — the entire struct becomes mutable when mut is used.

struct_def_mistake2.rs
struct Point {
    x: f64,
    y: f64,
}

fn main() {
    let p = Point { x: 1.0, y: 2.0 }; // no mut

    // Attempting to modify a field causes an error.
    p.x = 3.0; // compile error: cannot assign to `p.x`, as `p` is not declared as mutable
}

Compile with the following command:

rustc struct_def_mistake2.rs
error[E0594]: cannot assign to `p.x`, as `p` is not declared as mutable

Add mut to the variable declaration.

struct_def_fix2.rs
struct Point {
    x: f64,
    y: f64,
}

fn main() {
    let mut p = Point { x: 1.0, y: 2.0 }; // add mut
    p.x = 3.0;
    p.y = 4.0;
    println!("({}, {})", p.x, p.y); // (3, 4)
}

Compile with the following command:

rustc struct_def_fix2.rs
./struct_def_fix2
(3, 4)

Overview

Rust structs do not implement traits like Debug by default. To enable println!("{:?}", s) debug output, you need to add the #[derive(Debug)] attribute.

With the struct update syntax (..other), fields of types like String have their ownership moved. After the move, those fields on the original instance can no longer be accessed.

For adding methods to a struct, see impl / method definitions. For automatic trait implementations, see #[derive(Debug, Clone, PartialEq)].

If you find any errors or copyright issues, please .