]>
Commit | Line | Data |
---|---|---|
3b2f2976 | 1 | /// Used for indexing operations (`container[index]`) in immutable contexts. |
041b39d2 XL |
2 | /// |
3 | /// `container[index]` is actually syntactic sugar for `*container.index(index)`, | |
4 | /// but only when used as an immutable value. If a mutable value is requested, | |
5 | /// [`IndexMut`] is used instead. This allows nice things such as | |
3b2f2976 | 6 | /// `let value = v[index]` if the type of `value` implements [`Copy`]. |
041b39d2 | 7 | /// |
041b39d2 XL |
8 | /// # Examples |
9 | /// | |
10 | /// The following example implements `Index` on a read-only `NucleotideCount` | |
11 | /// container, enabling individual counts to be retrieved with index syntax. | |
12 | /// | |
13 | /// ``` | |
14 | /// use std::ops::Index; | |
15 | /// | |
16 | /// enum Nucleotide { | |
17 | /// A, | |
18 | /// C, | |
19 | /// G, | |
20 | /// T, | |
21 | /// } | |
22 | /// | |
23 | /// struct NucleotideCount { | |
24 | /// a: usize, | |
25 | /// c: usize, | |
26 | /// g: usize, | |
27 | /// t: usize, | |
28 | /// } | |
29 | /// | |
30 | /// impl Index<Nucleotide> for NucleotideCount { | |
31 | /// type Output = usize; | |
32 | /// | |
532ac7d7 | 33 | /// fn index(&self, nucleotide: Nucleotide) -> &Self::Output { |
041b39d2 XL |
34 | /// match nucleotide { |
35 | /// Nucleotide::A => &self.a, | |
36 | /// Nucleotide::C => &self.c, | |
37 | /// Nucleotide::G => &self.g, | |
38 | /// Nucleotide::T => &self.t, | |
39 | /// } | |
40 | /// } | |
41 | /// } | |
42 | /// | |
43 | /// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12}; | |
44 | /// assert_eq!(nucleotide_count[Nucleotide::A], 14); | |
45 | /// assert_eq!(nucleotide_count[Nucleotide::C], 9); | |
46 | /// assert_eq!(nucleotide_count[Nucleotide::G], 10); | |
47 | /// assert_eq!(nucleotide_count[Nucleotide::T], 12); | |
48 | /// ``` | |
49 | #[lang = "index"] | |
8faf50e0 | 50 | #[rustc_on_unimplemented( |
60c5eb7d XL |
51 | message = "the type `{Self}` cannot be indexed by `{Idx}`", |
52 | label = "`{Self}` cannot be indexed by `{Idx}`" | |
8faf50e0 | 53 | )] |
041b39d2 | 54 | #[stable(feature = "rust1", since = "1.0.0")] |
83c7162d XL |
55 | #[doc(alias = "]")] |
56 | #[doc(alias = "[")] | |
57 | #[doc(alias = "[]")] | |
6522a427 | 58 | #[const_trait] |
041b39d2 | 59 | pub trait Index<Idx: ?Sized> { |
3b2f2976 | 60 | /// The returned type after indexing. |
041b39d2 XL |
61 | #[stable(feature = "rust1", since = "1.0.0")] |
62 | type Output: ?Sized; | |
63 | ||
3b2f2976 | 64 | /// Performs the indexing (`container[index]`) operation. |
cdc7bbd5 XL |
65 | /// |
66 | /// # Panics | |
67 | /// | |
68 | /// May panic if the index is out of bounds. | |
041b39d2 | 69 | #[stable(feature = "rust1", since = "1.0.0")] |
f9f354fc | 70 | #[track_caller] |
041b39d2 XL |
71 | fn index(&self, index: Idx) -> &Self::Output; |
72 | } | |
73 | ||
3b2f2976 | 74 | /// Used for indexing operations (`container[index]`) in mutable contexts. |
041b39d2 XL |
75 | /// |
76 | /// `container[index]` is actually syntactic sugar for | |
77 | /// `*container.index_mut(index)`, but only when used as a mutable value. If | |
78 | /// an immutable value is requested, the [`Index`] trait is used instead. This | |
3b2f2976 | 79 | /// allows nice things such as `v[index] = value`. |
041b39d2 | 80 | /// |
041b39d2 XL |
81 | /// # Examples |
82 | /// | |
83 | /// A very simple implementation of a `Balance` struct that has two sides, where | |
84 | /// each can be indexed mutably and immutably. | |
85 | /// | |
86 | /// ``` | |
fc512014 | 87 | /// use std::ops::{Index, IndexMut}; |
041b39d2 XL |
88 | /// |
89 | /// #[derive(Debug)] | |
90 | /// enum Side { | |
91 | /// Left, | |
92 | /// Right, | |
93 | /// } | |
94 | /// | |
95 | /// #[derive(Debug, PartialEq)] | |
96 | /// enum Weight { | |
97 | /// Kilogram(f32), | |
98 | /// Pound(f32), | |
99 | /// } | |
100 | /// | |
101 | /// struct Balance { | |
102 | /// pub left: Weight, | |
3b2f2976 | 103 | /// pub right: Weight, |
041b39d2 XL |
104 | /// } |
105 | /// | |
106 | /// impl Index<Side> for Balance { | |
107 | /// type Output = Weight; | |
108 | /// | |
416331ca | 109 | /// fn index(&self, index: Side) -> &Self::Output { |
5e7ed085 | 110 | /// println!("Accessing {index:?}-side of balance immutably"); |
041b39d2 XL |
111 | /// match index { |
112 | /// Side::Left => &self.left, | |
113 | /// Side::Right => &self.right, | |
114 | /// } | |
115 | /// } | |
116 | /// } | |
117 | /// | |
118 | /// impl IndexMut<Side> for Balance { | |
416331ca | 119 | /// fn index_mut(&mut self, index: Side) -> &mut Self::Output { |
5e7ed085 | 120 | /// println!("Accessing {index:?}-side of balance mutably"); |
041b39d2 XL |
121 | /// match index { |
122 | /// Side::Left => &mut self.left, | |
123 | /// Side::Right => &mut self.right, | |
124 | /// } | |
125 | /// } | |
126 | /// } | |
127 | /// | |
3b2f2976 XL |
128 | /// let mut balance = Balance { |
129 | /// right: Weight::Kilogram(2.5), | |
130 | /// left: Weight::Pound(1.5), | |
131 | /// }; | |
132 | /// | |
133 | /// // In this case, `balance[Side::Right]` is sugar for | |
134 | /// // `*balance.index(Side::Right)`, since we are only *reading* | |
135 | /// // `balance[Side::Right]`, not writing it. | |
136 | /// assert_eq!(balance[Side::Right], Weight::Kilogram(2.5)); | |
137 | /// | |
138 | /// // However, in this case `balance[Side::Left]` is sugar for | |
139 | /// // `*balance.index_mut(Side::Left)`, since we are writing | |
140 | /// // `balance[Side::Left]`. | |
141 | /// balance[Side::Left] = Weight::Kilogram(3.0); | |
041b39d2 XL |
142 | /// ``` |
143 | #[lang = "index_mut"] | |
8faf50e0 | 144 | #[rustc_on_unimplemented( |
9fa01778 | 145 | on( |
60c5eb7d XL |
146 | _Self = "&str", |
147 | note = "you can use `.chars().nth()` or `.bytes().nth()` | |
9fa01778 XL |
148 | see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" |
149 | ), | |
150 | on( | |
60c5eb7d XL |
151 | _Self = "str", |
152 | note = "you can use `.chars().nth()` or `.bytes().nth()` | |
9fa01778 XL |
153 | see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" |
154 | ), | |
155 | on( | |
60c5eb7d XL |
156 | _Self = "std::string::String", |
157 | note = "you can use `.chars().nth()` or `.bytes().nth()` | |
9fa01778 XL |
158 | see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" |
159 | ), | |
60c5eb7d XL |
160 | message = "the type `{Self}` cannot be mutably indexed by `{Idx}`", |
161 | label = "`{Self}` cannot be mutably indexed by `{Idx}`" | |
8faf50e0 | 162 | )] |
041b39d2 | 163 | #[stable(feature = "rust1", since = "1.0.0")] |
83c7162d XL |
164 | #[doc(alias = "[")] |
165 | #[doc(alias = "]")] | |
166 | #[doc(alias = "[]")] | |
6522a427 EL |
167 | #[const_trait] |
168 | pub trait IndexMut<Idx: ?Sized>: ~const Index<Idx> { | |
3b2f2976 | 169 | /// Performs the mutable indexing (`container[index]`) operation. |
cdc7bbd5 XL |
170 | /// |
171 | /// # Panics | |
172 | /// | |
173 | /// May panic if the index is out of bounds. | |
041b39d2 | 174 | #[stable(feature = "rust1", since = "1.0.0")] |
f9f354fc | 175 | #[track_caller] |
041b39d2 XL |
176 | fn index_mut(&mut self, index: Idx) -> &mut Self::Output; |
177 | } |