about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authoriirelu <anna@bawk.space>2018-09-03 16:25:51 +0200
committeriirelu <anna@bawk.space>2018-09-03 16:25:51 +0200
commit047aac5cc60016b7c7f2a92f335b4a82b07ec59c (patch)
tree001046222170e710b1fde6cc27473585d64d7a73 /src/libstd
parentf3bb23191c7735eb8526db69d620a8c4ad705399 (diff)
downloadrust-047aac5cc60016b7c7f2a92f335b4a82b07ec59c.tar.gz
rust-047aac5cc60016b7c7f2a92f335b4a82b07ec59c.zip
Flesh out struct keyword docs
The whole keyword docs thing is pretty new in Rust's history and needs
some work before it's a shining gem. Here's hoping I can provide that.

I basically shoved in a bunch of the most important information from the
reference and the book, along with leaving links to both at the end. I
don't think keyword docs need to have complete detail, just all the
broad strokes, so if someone's confused about a usage of a keyword they
can look at the std documentation for that keyword.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/keyword_docs.rs104
1 files changed, 96 insertions, 8 deletions
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index d70cf132b3c..b5593e44f8b 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -59,21 +59,109 @@ mod let_keyword { }
 
 #[doc(keyword = "struct")]
 //
-/// The `struct` keyword.
+/// The keyword used to define structs.
 ///
-/// The `struct` keyword is used to define a struct type.
+/// Structs in Rust come in three flavours: Regular structs, tuple structs,
+/// and empty structs.
 ///
-/// Example:
+/// ```rust
+/// struct Regular {
+///     field1: f32,
+///     field2: String,
+///     pub field3: bool
+/// }
 ///
+/// struct Tuple(u32, String);
+///
+/// struct Empty;
 /// ```
-/// struct Foo {
-///     field1: u32,
-///     field2: String,
+///
+/// Regular structs are the most commonly used. Each field defined within them has a name and a
+/// type, and once defined can be accessed using `example_struct.field` syntax. The fields of a
+/// struct share its mutability, so `foo.bar = 2;` would only be valid if `foo` was mutable. Adding
+/// `pub` to a field makes it visible to code in other modules, as well as allowing it to be
+/// directly accessed and modified.
+///
+/// Tuple structs are similar to regular structs, but its fields have no names. They are used like
+/// tuples, with deconstruction possible via `let TupleStruct(x, y) = foo;` syntax.  For accessing
+/// individual variables, the same syntax is used as with regular tuples, namely `foo.0`, `foo.1`,
+/// etc, starting at zero.
+///
+/// Empty structs, or unit-like structs, are most commonly used as markers, for example
+/// [`PhantomData`]. Empty structs have a size of zero bytes, but unlike empty enums they can be
+/// instantiated, making them similar to the unit type `()`. Unit-like structs are useful when you
+/// need to implement a trait on something, but don't need to store any data inside it.
+///
+/// # Instantiation
+///
+/// Structs can be instantiated in a manner of different ways, each of which can be mixed and
+/// matched as needed. The most common way to make a new struct is via a constructor method such as
+/// `new()`, but when that isn't available (or you're writing the constructor itself), struct
+/// literal syntax is used:
+///
+/// ```rust
+/// # struct Foo { field1: f32, field2: String, etc: bool }
+/// let example = Foo {
+///     field1: 42.0,
+///     field2: "blah".to_string(),
+///     etc: true,
+/// };
+/// ```
+///
+/// It's only possible to directly instantiate a struct using struct literal syntax when all of its
+/// fields are visible to you.
+///
+/// There are a handful of shortcuts provided to make writing constructors more convenient, most
+/// common of which is the Field Init shorthand. When there is a variable and a field of the same
+/// name, the assignment can be simplified from `field: field` into simply `field`. The following
+/// example of a hypothetical constructor demonstrates this:
+///
+/// ```rust
+/// struct User {
+///     name: String,
+///     admin: bool,
+/// }
+///
+/// impl User {
+///     pub fn new(name: String) -> Self {
+///         Self {
+///             name,
+///             admin: false,
+///         }
+///     }
 /// }
 /// ```
 ///
-/// There are different kinds of structs. For more information, take a look at the
-/// [Rust Book][book].
+/// Another shortcut for struct instantiation is available when you need to make a new struct that
+/// shares most of a previous struct's values called struct update syntax:
+///
+/// ```rust
+/// # struct Foo { field1: String, field2: () }
+/// # let thing = Foo { field1: "".to_string(), field2: () };
+/// let updated_thing = Foo {
+///     field1: "a new value".to_string(),
+///     ..thing
+/// };
+/// ```
 ///
+/// Tuple structs are instantiated in the same way as tuples themselves, except with the struct's
+/// name as a prefix: `Foo(123, false, 0.1)`.
+///
+/// Empty structs are instantiated with just their name and nothing else. `let thing =
+/// EmptyStruct;`
+///
+///
+/// # Style conventions
+///
+/// Structs are always written in CamelCase, with few exceptions. While the trailing comma on a
+/// struct's list of fields can be omitted, it's usually kept for convenience in adding and
+/// removing fields down the line.
+///
+/// For more information on structs, take a look at the [Rust Book][book] or the
+/// [Reference][reference].
+///
+/// [`PhantomData`]: marker/struct.PhantomData.html
 /// [book]: https://doc.rust-lang.org/book/second-edition/ch05-01-defining-structs.html
+/// [reference]: https://doc.rust-lang.org/reference/items/structs.html
+
 mod struct_keyword { }