Skip to content

Commit bd8101d

Browse files
committed
Rollup merge of #24675 - steveklabnik:two_more_chapters, r=alexcrichton
Two more chapters of TRPL. The `type` one is pretty straightforward, but I wasn't really sure what to put for unsized types. I just explained the very basics, and the special bounds syntax. Thoughts on what else should go here? r? @alexcrichton
2 parents 231cb93 + defdc44 commit bd8101d

File tree

2 files changed

+130
-2
lines changed

2 files changed

+130
-2
lines changed

src/doc/trpl/type-aliases.md

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,76 @@
11
% `type` Aliases
22

3-
Coming soon
3+
The `type` keyword lets you declare an alias of another type:
4+
5+
```rust
6+
type Name = String;
7+
```
8+
9+
You can then use this type as if it were a real type:
10+
11+
```rust
12+
type Name = String;
13+
14+
let x: Name = "Hello".to_string();
15+
```
16+
17+
Note, however, that this is an _alias_, not a new type entirely. In other
18+
words, because Rust is strongly typed, you’d expect a comparison between two
19+
different types to fail:
20+
21+
```rust,ignore
22+
let x: i32 = 5;
23+
let y: i64 = 5;
24+
25+
if x == y {
26+
// ...
27+
}
28+
```
29+
30+
this gives
31+
32+
```text
33+
error: mismatched types:
34+
expected `i32`,
35+
found `i64`
36+
(expected i32,
37+
found i64) [E0308]
38+
if x == y {
39+
^
40+
```
41+
42+
But, if we had an alias:
43+
44+
```rust
45+
type Num = i32;
46+
47+
let x: i32 = 5;
48+
let y: Num = 5;
49+
50+
if x == y {
51+
// ...
52+
}
53+
```
54+
55+
This compiles without error. Values of a `Num` type are the same as a value of
56+
type `i32`, in every way.
57+
58+
You can also use type aliases with generics:
59+
60+
```rust
61+
use std::result;
62+
63+
enum ConcreteError {
64+
Foo,
65+
Bar,
66+
}
67+
68+
type Result<T> = result::Result<T, ConcreteError>;
69+
```
70+
71+
This creates a specialized version of the `Result` type, which always has a
72+
`ConcreteError` for the `E` part of `Result<T, E>`. This is commonly used
73+
in the standard library to create custom errors for each subsection. For
74+
example, [io::Result][ioresult].
75+
76+
[ioresult]: ../std/io/type.Result.html

src/doc/trpl/unsized-types.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,58 @@
11
% Unsized Types
22

3-
Coming Soon!
3+
Most types have a particular size, in bytes, that is knowable at compile time.
4+
For example, an `i32` is thirty-two bits big, or four bytes. However, there are
5+
some types which are useful to express, but do not have a defined size. These are
6+
called ‘unsized’ or ‘dynamically sized’ types. One example is `[T]`. This type
7+
represents a certain number of `T` in sequence. But we don’t know how many
8+
there are, so the size is not known.
9+
10+
Rust understands a few of these types, but they have some restrictions. There
11+
are three:
12+
13+
1. We can only manipulate an instance of an unsized type via a pointer. An
14+
`&[T]` works just fine, but a `[T]` does not.
15+
2. Variables and arguments cannot have dynamically sized types.
16+
3. Only the last field in a `struct` may have a dynamically sized type; the
17+
other fields must not. Enum variants must not have dynamically sized types as
18+
data.
19+
20+
So why bother? Well, because `[T]` can only be used behind a pointer, if we
21+
didn’t have language support for unsized types, it would be impossible to write
22+
this:
23+
24+
```rust,ignore
25+
impl Foo for str {
26+
```
27+
28+
or
29+
30+
```rust,ignore
31+
impl<T> Foo for [T] {
32+
```
33+
34+
Instead, you would have to write:
35+
36+
```rust,ignore
37+
impl Foo for &str {
38+
```
39+
40+
Meaning, this implementation would only work for [references][ref], and not
41+
other types of pointers. With this `impl`, all pointers, including (at some
42+
point, there are some bugs to fix first) user-defined custom smart pointers,
43+
can use this `impl`.
44+
45+
# ?Sized
46+
47+
If you want to write a function that accepts a dynamically sized type, you
48+
can use the special bound, `?Sized`:
49+
50+
```rust
51+
struct Foo<T: ?Sized> {
52+
f: T,
53+
}
54+
```
55+
56+
This `?`, read as “T may be `Sized`”, means that this bound is special: it
57+
lets us match more kinds, not less. It’s almost like every `T` implicitly has
58+
`T: Sized`, and the `?` undoes this default.

0 commit comments

Comments
 (0)