]> git.proxmox.com Git - rustc.git/blame - src/doc/style/features/types/newtype.md
Imported Upstream version 1.2.0+dfsg1
[rustc.git] / src / doc / style / features / types / newtype.md
CommitLineData
85aaf69f
SL
1% The newtype pattern
2
3A "newtype" is a tuple or `struct` with a single field. The terminology is borrowed from Haskell.
4
5Newtypes are a zero-cost abstraction: they introduce a new, distinct name for an
6existing type, with no runtime overhead when converting between the two types.
7
8### Use newtypes to provide static distinctions. [FIXME: needs RFC]
9
10Newtypes can statically distinguish between different interpretations of an
11underlying type.
12
13For example, a `f64` value might be used to represent a quantity in miles or in
14kilometers. Using newtypes, we can keep track of the intended interpretation:
15
16```rust
17struct Miles(pub f64);
18struct Kilometers(pub f64);
19
20impl Miles {
21 fn as_kilometers(&self) -> Kilometers { ... }
22}
23impl Kilometers {
24 fn as_miles(&self) -> Miles { ... }
25}
26```
27
28Once we have separated these two types, we can statically ensure that we do not
29confuse them. For example, the function
30
31```rust
32fn are_we_there_yet(distance_travelled: Miles) -> bool { ... }
33```
34
35cannot accidentally be called with a `Kilometers` value. The compiler will
36remind us to perform the conversion, thus averting certain
37[catastrophic bugs](http://en.wikipedia.org/wiki/Mars_Climate_Orbiter).
38
39### Use newtypes with private fields for hiding. [FIXME: needs RFC]
40
41A newtype can be used to hide representation details while making precise
42promises to the client.
43
44For example, consider a function `my_transform` that returns a compound iterator
45type `Enumerate<Skip<vec::MoveItems<T>>>`. We wish to hide this type from the
62682a34 46client, so that the client's view of the return type is roughly `Iterator<(usize,
85aaf69f
SL
47T)>`. We can do so using the newtype pattern:
48
49```rust
50struct MyTransformResult<T>(Enumerate<Skip<vec::MoveItems<T>>>);
62682a34 51impl<T> Iterator<(usize, T)> for MyTransformResult<T> { ... }
85aaf69f
SL
52
53fn my_transform<T, Iter: Iterator<T>>(iter: Iter) -> MyTransformResult<T> {
54 ...
55}
56```
57
58Aside from simplifying the signature, this use of newtypes allows us to make a
59expose and promise less to the client. The client does not know _how_ the result
60iterator is constructed or represented, which means the representation can
61change in the future without breaking client code.
62
63> **[FIXME]** Interaction with auto-deref.
64
65### Use newtypes to provide cost-free _views_ of another type. **[FIXME]**
66
67> **[FIXME]** Describe the pattern of using newtypes to provide a new set of
68> inherent or trait methods, providing a different perspective on the underlying
69> type.