构造函数

创建用户定义类型的实例只有一种方法:命名它,并一次性初始化它的所有字段

#![allow(unused)]
fn main() {
struct Foo {
    a: u8,
    b: u32,
    c: bool,
}

enum Bar {
    X(u32),
    Y(bool),
}

struct Unit;

let foo = Foo { a: 0, b: 1, c: false };
let bar = Bar::X(0);
let empty = Unit;
}

就是这样。你创建类型实例的所有其他方式都只是调用一个普通的函数,该函数执行一些操作,最终归结为唯一真正的构造函数。

与 C++ 不同,Rust 没有提供大量内置的构造函数类型。没有复制、默认、赋值、移动或任何构造函数。造成这种情况的原因有很多,但主要归结于 Rust 的显式哲学。

移动构造函数在 Rust 中没有意义,因为我们不允许类型“关心”它们在内存中的位置。每个类型都必须准备好被盲目地 memcopied 到内存中的其他位置。这意味着纯粹的堆栈上但仍然可移动的侵入式链表在 Rust 中根本不可能(安全地)实现。

赋值和复制构造函数也不存在,因为移动语义是 Rust 中唯一的语义。最多 x = y 只是将 y 的位移动到 x 变量中。Rust 提供了两种机制来提供 C++ 的面向复制的语义:CopyClone。Clone 是我们复制构造函数的道德等价物,但它永远不会被隐式调用。您必须显式调用您想要克隆的元素上的 clone。Copy 是 Clone 的一个特殊情况,其中实现只是“复制位”。Copy 类型在被移动时会被隐式克隆,但由于 Copy 的定义,这只是意味着不将旧副本视为未初始化——一个空操作。

虽然 Rust 提供了一个 Default 特性来指定默认构造函数的道德等价物,但这个特性很少使用。这是因为变量不会被隐式初始化。Default 基本上只对泛型编程有用。在具体的上下文中,类型将为任何类型的“默认”构造函数提供静态的 new 方法。这与其他语言中的 new 没有关系,也没有特殊的含义。这只是一个命名约定。

TODO:讨论“placement new”?