about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSteve Klabnik <steve@steveklabnik.com>2015-04-21 19:44:54 -0400
committerSteve Klabnik <steve@steveklabnik.com>2015-04-22 13:27:13 -0400
commitdefdc4418a2da483f8adeb2928c1ba1cddc5f7de (patch)
tree0a1a5af8a5b9fec67fdcbb6be56c88369492ed1f
parent3860240b0e124f38483ea4bd070b61d362871ece (diff)
downloadrust-defdc4418a2da483f8adeb2928c1ba1cddc5f7de.tar.gz
rust-defdc4418a2da483f8adeb2928c1ba1cddc5f7de.zip
TRPL: type aliases and unsized types
-rw-r--r--src/doc/trpl/type-aliases.md75
-rw-r--r--src/doc/trpl/unsized-types.md57
2 files changed, 130 insertions, 2 deletions
diff --git a/src/doc/trpl/type-aliases.md b/src/doc/trpl/type-aliases.md
index fffa0ae1383..d175da35f5e 100644
--- a/src/doc/trpl/type-aliases.md
+++ b/src/doc/trpl/type-aliases.md
@@ -1,3 +1,76 @@
 % `type` Aliases
 
-Coming soon
+The `type` keyword lets you declare an alias of another type:
+
+```rust
+type Name = String;
+```
+
+You can then use this type as if it were a real type:
+
+```rust
+type Name = String;
+
+let x: Name = "Hello".to_string();
+```
+
+Note, however, that this is an _alias_, not a new type entirely. In other
+words, because Rust is strongly typed, you’d expect a comparison between two
+different types to fail:
+
+```rust,ignore
+let x: i32 = 5;
+let y: i64 = 5;
+
+if x == y {
+   // ...
+}
+```
+
+this gives
+
+```text
+error: mismatched types:
+ expected `i32`,
+    found `i64`
+(expected i32,
+    found i64) [E0308]
+     if x == y {
+             ^
+```
+
+But, if we had an alias:
+
+```rust
+type Num = i32;
+
+let x: i32 = 5;
+let y: Num = 5;
+
+if x == y {
+   // ...
+}
+```
+
+This compiles without error. Values of a `Num` type are the same as a value of
+type `i32`, in every way.
+
+You can also use type aliases with generics:
+
+```rust
+use std::result;
+
+enum ConcreteError {
+    Foo,
+    Bar,
+}
+
+type Result<T> = result::Result<T, ConcreteError>;
+```
+
+This creates a specialized version of the `Result` type, which always has a
+`ConcreteError` for the `E` part of `Result<T, E>`. This is commonly used
+in the standard library to create custom errors for each subsection. For
+example, [io::Result][ioresult].
+
+[ioresult]: ../std/io/type.Result.html
diff --git a/src/doc/trpl/unsized-types.md b/src/doc/trpl/unsized-types.md
index f307f23f011..756abeff06d 100644
--- a/src/doc/trpl/unsized-types.md
+++ b/src/doc/trpl/unsized-types.md
@@ -1,3 +1,58 @@
 % Unsized Types
 
-Coming Soon!
+Most types have a particular size, in bytes, that is knowable at compile time.
+For example, an `i32` is thirty-two bits big, or four bytes. However, there are
+some types which are useful to express, but do not have a defined size. These are
+called ‘unsized’ or ‘dynamically sized’ types. One example is `[T]`. This type
+represents a certain number of `T` in sequence. But we don’t know how many
+there are, so the size is not known.
+
+Rust understands a few of these types, but they have some restrictions. There
+are three:
+
+1. We can only manipulate an instance of an unsized type via a pointer. An
+   `&[T]` works just fine, but a `[T]` does not.
+2. Variables and arguments cannot have dynamically sized types.
+3. Only the last field in a `struct` may have a dynamically sized type; the
+   other fields must not. Enum variants must not have dynamically sized types as
+   data.
+
+So why bother? Well, because `[T]` can only be used behind a pointer, if we
+didn’t have language support for unsized types, it would be impossible to write
+this:
+
+```rust,ignore
+impl Foo for str {
+```
+
+or
+
+```rust,ignore
+impl<T> Foo for [T] {
+```
+
+Instead, you would have to write:
+
+```rust,ignore
+impl Foo for &str {
+```
+
+Meaning, this implementation would only work for [references][ref], and not
+other types of pointers. With this `impl`, all pointers, including (at some
+point, there are some bugs to fix first) user-defined custom smart pointers,
+can use this `impl`.
+
+# ?Sized
+
+If you want to write a function that accepts a dynamically sized type, you
+can use the special bound, `?Sized`:
+
+```rust
+struct Foo<T: ?Sized> {
+    f: T,
+}
+```
+
+This `?`, read as “T may be `Sized`”,  means that this bound is special: it
+lets us match more kinds, not less. It’s almost like every `T` implicitly has
+`T: Sized`, and the `?` undoes this default.