Добавить объявление

Простое копирование структуры с частичными изменениями в Rust

При работе со структурами в Rust часто возникает необходимость создать новый экземпляр, который отличается от существующего всего несколькими полями. Вместо ручного копирования каждого поля, Rust предлагает элегантное решение.

Традиционный подход требует явного копирования всех полей:


#[derive(Debug)]
struct User {
name: String,
age: u32,
active: bool,
email: String
}

let user1 = User {
name: String::from("Alice"),
age: 30,
active: true,
email: String::from("alice@example.com")
};

// Многословно и подвержено ошибкам
let user2 = User {
name: String::from("Bob"),
age: user1.age,
active: user1.active,
email: user1.email
};

Элегантное решение:


#[derive(Debug, Clone)]
struct User {
name: String,
age: u32,
active: bool,
email: String
}

let user1 = User {
name: String::from("Alice"),
age: 30,
active: true,
email: String::from("alice@example.com")
};

// Чисто и элегантно
let user2 = User {
name: String::from("Bob"),
..user1 // Копируем все остальные поля из user1
};

Ключевые моменты:


  • .. оператор копирует все неуказанные поля из исходной структуры.

  • Порядок важен: поля указываются перед ..

  • Требует трейта Clone для типов, которые не являются Copy.

Важно:


  • .. копирует ВСЕ неуказанные поля.

  • Поля с типами без Copy (например String) перемещаются.

  • Чтобы сохранить исходную структуру, используйте .clone():


let user2 = User {
name: "Bob".into(),
..user1.clone() // Теперь user1 останется валидным
};

Вывод:


Синтаксис структурного обновления .. это небольшая, но мощная особенность Rust, которая делает код чище и безопаснее. Вместо ручного копирования десятков полей достаточно указать только те, что изменяются, и добавить ..исходная_структура. Компилятор позаботится обо всем остальном, гарантируя, что все поля будут корректно проинициализированы, а владение данными предсказуемым. Это не просто синтаксический сахар, а инструмент для написания выразительного и надежного кода.
12.12.2025 11 212