原文链接:https://doc.rust-lang.org/nomicon/constructors.html

构造函数

创建一个自定义类型的实例的方法只有一种:先命名,然后一次性初始化它的所有成员:

  1. struct Foo {
  2. a: u8,
  3. b:u32,
  4. c: bool,
  5. }
  6. enum Bar {
  7. X(u32),
  8. Y(bool),
  9. }
  10. struct Unit;
  11. let foo = Foo { a: 0, b: 1, c: false };
  12. let bar = Bar::X(0);
  13. let empty = Unit;

就是这样。其他的所谓创建类型实例的方式,不过是调用一些函数,而函数的底层还是要依赖于这个真正的构造函数。

和C++不同,Rust没有很多不同种类的构造函数,比如拷贝、默认、赋值、移动、还有其他各种构造函数。之所以这样的原因有很多,不过归根结底还是因为Rust显式化的设计哲学。

移动构造函数对于Rust没什么用,因为我们并不需要让类型关心它们在内存上的位置。没一个类型都有可能随时被memcopy到内存中其他的位置上。这也意味和那种存储于栈上却依然可以移动的侵入式链表在Rust中是不可能(安全地)存在的。

复制和拷贝构造函数也是不存在的,因为Rust中的类型有且仅有移动语义。x = y只是将y的字节移动到x的变量中。Rust倒是提供了两种和C++中的copy语义相似的功能:CopyCloneClone很像是拷贝构造函数,但是它不会被隐式调用。你必须在需要复制的元素上显式调用clone方法、CopyClone的一个特例,它的实现只会拷贝字节码。Copy类型在移动的时候会隐式地复制,但是因为Copy的定义,这个方法只是不把旧的值设置为未初始化而已——其实是一个no-op。

虽然Rust确实有一个Default trait,它与默认构造函数很相似,但是这个trait极少被用到。这是因为变量不会被隐式初始化Default一般只有在泛型编程中才有用。而具体的类型会提供一个new静态方法来实现默认构造函数的功能。这个和其他语言中的new关键字没什么关系,也没有什么特殊的含义。它仅仅是一个明明习惯而已。

TODO:介绍“placement new”?