]> git.proxmox.com Git - rustc.git/blob - src/doc/edition-guide/src/rust-2018/trait-system/associated-constants.md
New upstream version 1.53.0+dfsg1
[rustc.git] / src / doc / edition-guide / src / rust-2018 / trait-system / associated-constants.md
1 # Associated constants
2
3 ![Minimum Rust version: 1.20](https://img.shields.io/badge/Minimum%20Rust%20Version-1.20-brightgreen.svg)
4
5 You can define traits, structs, and enums that have “associated functions”:
6
7 ```rust
8 struct Struct;
9
10 impl Struct {
11 fn foo() {
12 println!("foo is an associated function of Struct");
13 }
14 }
15
16 fn main() {
17 Struct::foo();
18 }
19 ```
20
21 These are called “associated functions” because they are functions that are
22 associated with the type, that is, they’re attached to the type itself, and
23 not any particular instance.
24
25 Rust 1.20 adds the ability to define “associated constants” as well:
26
27 ```rust
28 struct Struct;
29
30 impl Struct {
31 const ID: u32 = 0;
32 }
33
34 fn main() {
35 println!("the ID of Struct is: {}", Struct::ID);
36 }
37 ```
38
39 That is, the constant `ID` is associated with `Struct`. Like functions,
40 associated constants work with traits and enums as well.
41
42 Traits have an extra ability with associated constants that gives them some
43 extra power. With a trait, you can use an associated constant in the same way
44 you’d use an associated type: by declaring it, but not giving it a value. The
45 implementor of the trait then declares its value upon implementation:
46
47 ```rust
48 trait Trait {
49 const ID: u32;
50 }
51
52 struct Struct;
53
54 impl Trait for Struct {
55 const ID: u32 = 5;
56 }
57
58 fn main() {
59 println!("{}", Struct::ID);
60 }
61 ```
62
63 Before this feature, if you wanted to make a trait that represented floating
64 point numbers, you’d have to write this:
65
66 ```rust
67 trait Float {
68 fn nan() -> Self;
69 fn infinity() -> Self;
70 // ...
71 }
72 ```
73
74 This is slightly unwieldy, but more importantly, because they’re functions,
75 they cannot be used in constant expressions, even though they only return a
76 constant. Because of this, a design for `Float` would also have to include
77 constants as well:
78
79 ```rust,ignore
80 mod f32 {
81 const NAN: f32 = 0.0f32 / 0.0f32;
82 const INFINITY: f32 = 1.0f32 / 0.0f32;
83
84 impl Float for f32 {
85 fn nan() -> Self {
86 f32::NAN
87 }
88 fn infinity() -> Self {
89 f32::INFINITY
90 }
91 }
92 }
93 ```
94
95 Associated constants let you do this in a much cleaner way. This trait
96 definition:
97
98 ```rust
99 trait Float {
100 const NAN: Self;
101 const INFINITY: Self;
102 // ...
103 }
104 ```
105
106 Leads to this implementation:
107
108 ```rust,ignore
109 mod f32 {
110 impl Float for f32 {
111 const NAN: f32 = 0.0f32 / 0.0f32;
112 const INFINITY: f32 = 1.0f32 / 0.0f32;
113 }
114 }
115 ```
116
117 much cleaner, and more versatile.