Constructors

There is exactly one way to create an instance of a user-defined type: name it,and initialize all its fields at once:

  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;

That’s it. Every other way you make an instance of a type is just calling atotally vanilla function that does some stuff and eventually bottoms out to TheOne True Constructor.

Unlike C++, Rust does not come with a slew of built-in kinds of constructor.There are no Copy, Default, Assignment, Move, or whatever constructors. Thereasons for this are varied, but it largely boils down to Rust’s philosophy ofbeing explicit.

Move constructors are meaningless in Rust because we don’t enable types to“care” about their location in memory. Every type must be ready for it to beblindly memcopied to somewhere else in memory. This means pure on-the-stack-but-still-movable intrusive linked lists are simply not happening in Rust (safely).

Assignment and copy constructors similarly don’t exist because move semanticsare the only semantics in Rust. At most x = y just moves the bits of y intothe x variable. Rust does provide two facilities for providing C++’s copy-oriented semantics: Copy and Clone. Clone is our moral equivalent of a copyconstructor, but it’s never implicitly invoked. You have to explicitly callclone on an element you want to be cloned. Copy is a special case of Clonewhere the implementation is just “copy the bits”. Copy types are implicitlycloned whenever they’re moved, but because of the definition of Copy this justmeans not treating the old copy as uninitialized — a no-op.

While Rust provides a Default trait for specifying the moral equivalent of adefault constructor, it’s incredibly rare for this trait to be used. This isbecause variables aren’t implicitly initialized. Default is basicallyonly useful for generic programming. In concrete contexts, a type will provide astatic new method for any kind of “default” constructor. This has no relationto new in other languages and has no special meaning. It’s just a namingconvention.

TODO: talk about “placement new”?