Выражения структур
Syntax
StructExpression →
PathInExpression { ( StructExprFields | StructBase )? }
StructExprFields →
StructExprField ( , StructExprField )* ( , StructBase | ,? )
StructExprField →
OuterAttribute*
(
IDENTIFIER
| ( IDENTIFIER | TUPLE_INDEX ) : Expression
)
StructBase → .. Expression
Выражение структуры создает значение структуры, варианта перечисления или объединения. Оно состоит из пути к элементу структуры, варианта перечисления или объединения, за которым следуют значения полей этого элемента.
Следующие примеры являются выражениями структур:
#![allow(unused)] fn main() { struct Point { x: f64, y: f64 } struct NothingInMe { } mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: usize } } enum Enum { Variant {} } Point {x: 10.0, y: 20.0}; NothingInMe {}; let u = game::User {name: "Joe", age: 35, score: 100_000}; Enum::Variant {}; }
Note
Кортежные структуры и кортежные варианты перечислений обычно создаются с использованием выражения вызова, ссылающегося на конструктор в пространстве имен значений. Они отличаются от выражения структуры с фигурными скобками, ссылающегося на конструктор в пространстве имен типов.
#![allow(unused)] fn main() { struct Position(i32, i32, i32); Position(0, 0, 0); // Обычный способ создания кортежной структуры. let c = Position; // `c` - это функция, принимающая 3 аргумента. let pos = c(8, 6, 7); // Создает значение `Position`. enum Version { Triple(i32, i32, i32) }; Version::Triple(0, 0, 0); let f = Version::Triple; let ver = f(8, 6, 7); }Последний сегмент пути вызова не может ссылаться на псевдоним типа:
#![allow(unused)] fn main() { trait Tr { type T; } impl<T> Tr for T { type T = T; } struct Tuple(); enum Enum { Tuple() } // <Unit as Tr>::T(); // вызывает ошибку -- `::T` это тип, а не значение <Enum as Tr>::T::Tuple(); // OK }
Структуры-единицы и варианты перечислений-единицы обычно создаются с использованием выражения пути, ссылающегося на константу в пространстве имен значений.
#![allow(unused)] fn main() { struct Gamma; // Значение-единица Gamma, ссылающееся на константу в пространстве имен значений. let a = Gamma; // Точно такое же значение, как `a`, но созданное с использованием выражения структуры // ссылающегося на пространство имен типов. let b = Gamma {}; enum ColorSpace { Oklch } let c = ColorSpace::Oklch; let d = ColorSpace::Oklch {}; }
Выражение структуры с полями
Выражение структуры с полями, заключенными в фигурные скобки, позволяет указать значение для каждого отдельного поля в любом порядке. Имя поля отделяется от его значения двоеточием.
Значение типа объединения может быть создано только с использованием этого синтаксиса, и оно должно указывать ровно одно поле.
Синтаксис функционального обновления
Выражение структуры, которое конструирует значение типа структуры, может заканчиваться синтаксисом .., за которым следует выражение, обозначающее функциональное обновление.
Выражение после .. (база) должно иметь тот же тип структуры, что и новая структура, которая формируется.
Все выражение использует заданные значения для указанных полей и перемещает или копирует оставшиеся поля из базового выражения.
Как и во всех выражениях структур, все поля структуры должны быть видимыми, даже те, которые не указаны явно.
#![allow(unused)] fn main() { struct Point3d { x: i32, y: i32, z: i32 } let mut base = Point3d {x: 1, y: 2, z: 3}; let y_ref = &mut base.y; Point3d {y: 0, z: 10, .. base}; // OK, доступен только base.x drop(y_ref); }
Выражения структур не могут использоваться непосредственно в заголовке выражения цикла или if, или в рассматриваемом выражении выражения if let или match. Однако выражения структур могут использоваться в этих ситуациях, если они находятся внутри другого выражения, например, внутри скобок.
Имена полей могут быть десятичными целыми числами для указания индексов при конструировании кортежных структур. Это может быть использовано с базовыми структурами для заполнения оставшихся не указанных индексов:
#![allow(unused)] fn main() { struct Color(u8, u8, u8); let c1 = Color(0, 0, 0); // Обычный способ создания кортежной структуры. let c2 = Color{0: 255, 1: 127, 2: 0}; // Указание полей по индексу. let c3 = Color{1: 0, ..c2}; // Заполнить все остальные поля с использованием базовой структуры. }
Сокращенная инициализация полей структуры
При инициализации структуры данных (структуры, перечисления, объединения) с именованными (но не нумерованными) полями разрешается писать fieldname как сокращение для fieldname: fieldname.
Это позволяет компактный синтаксис с меньшим дублированием.
Например:
#![allow(unused)] fn main() { struct Point3d { x: i32, y: i32, z: i32 } let x = 0; let y_value = 0; let z = 0; Point3d { x: x, y: y_value, z: z }; Point3d { x, y: y_value, z }; }