]> git.lizzy.rs Git - rust.git/blob - src/doc/style/features/types/newtype.md
Changed issue number to 36105
[rust.git] / src / doc / style / features / types / newtype.md
1 % The newtype pattern
2
3 A "newtype" is a tuple or `struct` with a single field. The terminology is borrowed from Haskell.
4
5 Newtypes are a zero-cost abstraction: they introduce a new, distinct name for an
6 existing type, with no runtime overhead when converting between the two types.
7
8 ### Use newtypes to provide static distinctions. [FIXME: needs RFC]
9
10 Newtypes can statically distinguish between different interpretations of an
11 underlying type.
12
13 For example, a `f64` value might be used to represent a quantity in miles or in
14 kilometers. Using newtypes, we can keep track of the intended interpretation:
15
16 ```rust,ignore
17 struct Miles(pub f64);
18 struct Kilometers(pub f64);
19
20 impl Miles {
21     fn as_kilometers(&self) -> Kilometers { ... }
22 }
23 impl Kilometers {
24     fn as_miles(&self) -> Miles { ... }
25 }
26 ```
27
28 Once we have separated these two types, we can statically ensure that we do not
29 confuse them. For example, the function
30
31 ```rust,ignore
32 fn are_we_there_yet(distance_travelled: Miles) -> bool { ... }
33 ```
34
35 cannot accidentally be called with a `Kilometers` value. The compiler will
36 remind 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
41 A newtype can be used to hide representation details while making precise
42 promises to the client.
43
44 For example, consider a function `my_transform` that returns a compound iterator
45 type `Enumerate<Skip<vec::MoveItems<T>>>`. We wish to hide this type from the
46 client, so that the client's view of the return type is roughly `Iterator<(usize,
47 T)>`. We can do so using the newtype pattern:
48
49 ```rust,ignore
50 struct MyTransformResult<T>(Enumerate<Skip<vec::MoveItems<T>>>);
51 impl<T> Iterator<(usize, T)> for MyTransformResult<T> { ... }
52
53 fn my_transform<T, Iter: Iterator<T>>(iter: Iter) -> MyTransformResult<T> {
54     ...
55 }
56 ```
57
58 Aside from simplifying the signature, this use of newtypes allows us to make a
59 expose and promise less to the client. The client does not know _how_ the result
60 iterator is constructed or represented, which means the representation can
61 change 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.