结构体表达式

语法
结构体表达式 :
      结构体表达式结构
   | 结构体表达式元组
   | 结构体表达式单元

结构体表达式结构 :
   表达式中路径 { (结构体表达式字段组 | 结构省略)? }

结构体表达式字段组 :
   结构体表达式字段 (, 结构体表达式字段)* (, 结构省略 | ,?)

结构体表达式字段 :
   外围属性 *
   (
         标识符
      | (标识符 | 元组索引) : 表达式
   )

结构省略 :
   .. 表达式

结构体表达式元组 :
   表达式中路径 (
      ( 表达式 (, 表达式)* ,? )?
   )

结构体表达式单元 : 表达式中路径

结构体表达式 用于创建结构体、枚举或联合体值。 它由指向 结构体枚举变体联合体 条目的路径,以及该条目字段的值组成。 结构体表达式有三种形式:结构体、元组和单元结构体。

以下是结构体表达式的示例:

#![allow(unused)]
fn main() {
struct Point { x: f64, y: f64 }
struct NothingInMe { }
struct TuplePoint(f64, f64);
mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: usize } }
struct Cookie; fn some_fn<T>(t: T) {}
Point {x: 10.0, y: 20.0};
NothingInMe {};
TuplePoint(10.0, 20.0);
TuplePoint { 0: 10.0, 1: 20.0 }; // 得到的结果与上一行相同
let u = game::User {name: "Joe", age: 35, score: 100_000};
some_fn::<Cookie>(Cookie);
}

字段结构体表达式

带有花括号括起来的字段结构体表达式允许你以任何顺序指定每个单独字段的值。字段名称用冒号与其值分开。

联合体 类型的值只能使用此语法创建,并且必须指定一个字段。

函数式更新语法

用于构造结构体类型值的结构体表达式可以用 .. 语法结尾,后跟表达式,表示函数式更新。 .. 后面的表达式 (基表达式) 必须与新结构体类型相同。

整个表达式使用给定值填充指定的字段,并将其余字段从基表达式中移动或复制。 与所有结构体表达式一样,结构体的所有字段都必须是 可见的 ,即使未显式命名。

#![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}; // 成功, 仅 base.x 是被访问
drop(y_ref);
}

带大括号的结构体表达式不能直接用于 loopif 表达式头部,也不能用于 if letmatch 表达式的 被匹配项。 但是,如果结构体表达式在另一个表达式中,例如在 括号 中,它们就可以在这些情况下使用。

字段名称可以是十进制整数值,用于指定用于构造元组结构体的索引。这可以与基础结构体一起使用,以填充未指定的其余索引:

#![allow(unused)]
fn main() {
struct Color(u8, u8, u8); // 定义一个名为 Color 的元组结构体
let c1 = Color(0, 0, 0); // 创建元组结构体实例的一般方式
let c2 = Color{0: 255, 1: 127, 2: 0}; // 按索引指定结构体字段的值
let c3 = Color{1: 0, ..c2}; // 使用基础结构体填充所有其他字段
}

结构体字段初始化的简写语法

在初始化具有命名 (但不是编号) 字段的数据结构 (struct、enum、union) 时,可以使用 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 };
}

元组结构体表达式

用括号括起来的字段的结构体表达式构造元组结构体。 虽然为了完整性而在此列出了它作为一个特定的表达式,但它等同于对元组结构体构造函数的 调用表达式 。 例如:

#![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` 值
}

单元结构体表达式

单元结构体表达式只是指向一个空结构体条目的路径。 这个路径指向该结构体的值的隐式常量。 单元结构体的值也可以用一个没有字段的结构体表达式构造。例如:

#![allow(unused)]
fn main() {
struct Gamma;
let a = Gamma;  // Gamma 单元值。
let b = Gamma{};  // 与 `a` 完全相同的值。
}