]> git.lizzy.rs Git - rust.git/commitdiff
expand on ctors
authorAlexis Beingessner <a.beingessner@gmail.com>
Tue, 7 Jul 2015 03:25:14 +0000 (20:25 -0700)
committerAlexis Beingessner <a.beingessner@gmail.com>
Tue, 7 Jul 2015 03:25:14 +0000 (20:25 -0700)
constructors.md

index 8069776c0aafcc4116dd2a3b0ec6759556fe0bdf..99bcf5e283ee38a3667e482fd9eb498c454ffc6f 100644 (file)
@@ -1,26 +1,55 @@
 % Constructors
 
-Unlike C++, Rust does not come with a slew of builtin
-kinds of constructor. There are no Copy, Default, Assignment, Move, or whatever constructors.
-This largely has to do with Rust's philosophy of being 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 be blindly 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 semantics are the *default*
-in rust. At most `x = y` just moves the bits of y into the x variable. Rust does provide two
-facilities for going back to C++'s copy-oriented semantics: `Copy` and `Clone`. Clone is our
-moral equivalent of a copy constructor, but it's never implicitly invoked. You have to explicitly
-call `clone` on an element you want to be cloned. Copy is a special case of Clone where the
-implementation is just "copy the bits". Copy types *are* implicitly
-cloned whenever they're moved, but because of the definition of Copy this just means *not*
-treating the old copy as uninitialized -- a no-op.
-
-While Rust provides a `Default` trait for specifying the moral equivalent of a default
-constructor, it's incredibly rare for this trait to be used. This is because variables
-[aren't implicitly initialized][uninit]. Default is basically only useful for generic
-programming. In concrete contexts, a type will provide a static `new` method for any
-kind of "default" constructor. This has no relation to `new` in other
-languages and has no special meaning. It's just a naming convention.
\ No newline at end of file
+There is exactly one way to create an instance of a user-defined type: name it,
+and initialize all its fields at once:
+
+```rust
+struct Foo {
+       a: u8,
+       b: u32,
+       c: bool,
+}
+
+enum Bar {
+       X(u32),
+       Y(bool),
+}
+
+struct Empty;
+
+let foo = Foo { a: 0, b: 1, c: false };
+let bar = Bar::X(0);
+let empty = Empty;
+```
+
+That's it. Every other way you make an instance of a type is just calling a
+totally vanilla function that does some stuff and eventually bottoms out to The
+One 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. The
+reasons for this are varied, but it largely boils down to Rust's philosophy
+of *being 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 be
+blindly 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 semantics
+are the *only* semantics in Rust. At most `x = y` just moves the bits of y into the x
+variable. Rust *does* provide two facilities for providing C++'s copy-oriented
+semantics: `Copy` and `Clone`. Clone is our moral equivalent of a copy
+constructor, but it's never implicitly invoked. You have to explicitly call
+`clone` on an element you want to be cloned. Copy is a special case of Clone
+where the implementation is just "copy the bits". Copy types *are* implicitly
+cloned whenever they're moved, but because of the definition of Copy this just
+means *not* treating the old copy as uninitialized -- a no-op.
+
+While Rust provides a `Default` trait for specifying the moral equivalent of a
+default constructor, it's incredibly rare for this trait to be used. This is
+because variables [aren't implicitly initialized][uninit]. Default is basically
+only useful for generic programming. In concrete contexts, a type will provide a
+static `new` method for any kind of "default" constructor. This has no relation
+to `new` in other languages and has no special meaning. It's just a naming
+convention.