Initializing Structs in Rust: Quick Start and Advanced Tricks

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why is Struct Initialization in Rust Not Boring?

\n\n

If you've ever written in Rust, you've probably encountered a moment when you want to say: "Why do I have to write field: field over and over again? It's obvious!"

\n\n

Yes, Rust is a strict, rigorous, and incredibly expressive language. But even it has room for syntactic sugar that makes code shorter, cleaner, and more pleasing to the eye. This is especially true for struct initialization — that very routine we do dozens of times a day.

\n\n

In this article, we will not just answer the popular Stack Overflow question: "Is there a faster/shorter way to initialize variables in a Rust struct?". We will break down all the methods — from basic to advanced — and show you how to write code that is simultaneously fast, readable, and idiomatic Rust.

\n\n

Ready to speed up your work with Rust struct? Let's go!

\n\n

1. The Classic Way: Explicit Field Naming

\n\n

Let's start with the basics. Suppose we have a User struct:

\n\n
struct User {\n    username: String,\n    email: String,\n    sign_in_count: u64,\n    active: bool,\n}
\n\n

Standard initialization looks like this:

\n\n
let user1 = User {\n    email: String::from("someone@example.com"),\n    username: String::from("someusername123"),\n    active: true,\n    sign_in_count: 1,\n};
\n\n

It's honest, it's explicit. But when you have 10-15 fields and the variable names match the field names — it starts to get annoying. You write email: email and feel like a bureaucrat filling out a form.

\n\n

The good news: Rust feels this too. And it came up with a solution.

\n\n

2. Field Init Shorthand: When the Variable Name Matches the Field

\n\n

Starting with Rust 1.17, you can use a shorthand notation if the variable name matches the struct field name. This is called field init shorthand.

\n\n
let email = String::from("someone@example.com");\nlet username = String::from("someusername123");\n\nlet user1 = User {\n    email,  // instead of email: email\n    username, // instead of username: username\n    active: true,\n    sign_in_count: 1,\n};
\n\n

Nice, right? Rust itself understands that email is both a variable and a field. This technique is especially handy when you pass function parameters that are already meaningfully named.

\n\n

When to use: always, when the variable name matches the field name. This is not just "faster to write", it's idiomatic Rust.

\n\n

3. Struct Update Syntax: Copying a Struct with Changes

\n\n

Suppose we already have user1, and we want to create user2, changing only the email. Do we have to rewrite all the fields? No!

\n\n
let user2 = User {\n    email: String::from("another@example.com"),\n    ..user1  // remaining fields are taken from user1\n};
\n\n

The .. operator is the struct update syntax. It tells the compiler: "Take all the remaining fields from user1". Important: after this, user1 will be partially moved (if the fields do not implement Copy), so be careful with ownership.

\n\n

This syntax saves tons of lines when you work with Rust struct initialization based on existing data.

\n\n

4. The Default Trait: Initialization with Defaults

\n\n

What if most fields should have standard values? For example, active: true and sign_in_count: 0? You can implement the Default trait:

\n\n
#[derive(Default)]\nstruct User {\n    username: String,\n    email: String,\n    active: bool,\n    sign_in_count: u64,\n}\n\n// Now:\nlet user_default = User::default();\n// username: "", email: "", active: false, sign_in_count: 0
\n\n

But wait!

Blogs

Book Recommendations