]> git.lizzy.rs Git - rust.git/blob - src/doc/tarpl/constructors.md
023dea08444a436f403fbdb209e326486d993e76
[rust.git] / src / doc / tarpl / constructors.md
1 % Constructors
2
3 There is exactly one way to create an instance of a user-defined type: name it,
4 and initialize all its fields at once:
5
6 ```rust
7 struct Foo {
8     a: u8,
9     b: u32,
10     c: bool,
11 }
12
13 enum Bar {
14     X(u32),
15     Y(bool),
16 }
17
18 struct Unit;
19
20 let foo = Foo { a: 0, b: 1, c: false };
21 let bar = Bar::X(0);
22 let empty = Unit;
23 ```
24
25 That's it. Every other way you make an instance of a type is just calling a
26 totally vanilla function that does some stuff and eventually bottoms out to The
27 One True Constructor.
28
29 Unlike C++, Rust does not come with a slew of built-in kinds of constructor.
30 There are no Copy, Default, Assignment, Move, or whatever constructors. The
31 reasons for this are varied, but it largely boils down to Rust's philosophy of
32 *being explicit*.
33
34 Move constructors are meaningless in Rust because we don't enable types to
35 "care" about their location in memory. Every type must be ready for it to be
36 blindly memcopied to somewhere else in memory. This means pure on-the-stack-but-
37 still-movable intrusive linked lists are simply not happening in Rust (safely).
38
39 Assignment and copy constructors similarly don't exist because move semantics
40 are the *only* semantics in Rust. At most `x = y` just moves the bits of y into
41 the x variable. Rust *does* provide two facilities for providing C++'s copy-
42 oriented semantics: `Copy` and `Clone`. Clone is our moral equivalent of a copy
43 constructor, but it's never implicitly invoked. You have to explicitly call
44 `clone` on an element you want to be cloned. Copy is a special case of Clone
45 where the implementation is just "copy the bits". Copy types *are* implicitly
46 cloned whenever they're moved, but because of the definition of Copy this just
47 means *not* treating the old copy as uninitialized -- a no-op.
48
49 While Rust provides a `Default` trait for specifying the moral equivalent of a
50 default constructor, it's incredibly rare for this trait to be used. This is
51 because variables [aren't implicitly initialized][uninit]. Default is basically
52 only useful for generic programming. In concrete contexts, a type will provide a
53 static `new` method for any kind of "default" constructor. This has no relation
54 to `new` in other languages and has no special meaning. It's just a naming
55 convention.
56
57 TODO: talk about "placement new"?
58
59 [uninit]: uninitialized.html