]> git.lizzy.rs Git - rust.git/blob - library/core/src/ops/index.rs
Fix font color for help button in ayu and dark themes
[rust.git] / library / core / src / ops / index.rs
1 /// Used for indexing operations (`container[index]`) in immutable contexts.
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
6 /// `let value = v[index]` if the type of `value` implements [`Copy`].
7 ///
8 /// [`IndexMut`]: ../../std/ops/trait.IndexMut.html
9 /// [`Copy`]: ../../std/marker/trait.Copy.html
10 ///
11 /// # Examples
12 ///
13 /// The following example implements `Index` on a read-only `NucleotideCount`
14 /// container, enabling individual counts to be retrieved with index syntax.
15 ///
16 /// ```
17 /// use std::ops::Index;
18 ///
19 /// enum Nucleotide {
20 ///     A,
21 ///     C,
22 ///     G,
23 ///     T,
24 /// }
25 ///
26 /// struct NucleotideCount {
27 ///     a: usize,
28 ///     c: usize,
29 ///     g: usize,
30 ///     t: usize,
31 /// }
32 ///
33 /// impl Index<Nucleotide> for NucleotideCount {
34 ///     type Output = usize;
35 ///
36 ///     fn index(&self, nucleotide: Nucleotide) -> &Self::Output {
37 ///         match nucleotide {
38 ///             Nucleotide::A => &self.a,
39 ///             Nucleotide::C => &self.c,
40 ///             Nucleotide::G => &self.g,
41 ///             Nucleotide::T => &self.t,
42 ///         }
43 ///     }
44 /// }
45 ///
46 /// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12};
47 /// assert_eq!(nucleotide_count[Nucleotide::A], 14);
48 /// assert_eq!(nucleotide_count[Nucleotide::C], 9);
49 /// assert_eq!(nucleotide_count[Nucleotide::G], 10);
50 /// assert_eq!(nucleotide_count[Nucleotide::T], 12);
51 /// ```
52 #[lang = "index"]
53 #[rustc_on_unimplemented(
54     message = "the type `{Self}` cannot be indexed by `{Idx}`",
55     label = "`{Self}` cannot be indexed by `{Idx}`"
56 )]
57 #[stable(feature = "rust1", since = "1.0.0")]
58 #[doc(alias = "]")]
59 #[doc(alias = "[")]
60 #[doc(alias = "[]")]
61 pub trait Index<Idx: ?Sized> {
62     /// The returned type after indexing.
63     #[stable(feature = "rust1", since = "1.0.0")]
64     type Output: ?Sized;
65
66     /// Performs the indexing (`container[index]`) operation.
67     #[stable(feature = "rust1", since = "1.0.0")]
68     #[track_caller]
69     fn index(&self, index: Idx) -> &Self::Output;
70 }
71
72 /// Used for indexing operations (`container[index]`) in mutable contexts.
73 ///
74 /// `container[index]` is actually syntactic sugar for
75 /// `*container.index_mut(index)`, but only when used as a mutable value. If
76 /// an immutable value is requested, the [`Index`] trait is used instead. This
77 /// allows nice things such as `v[index] = value`.
78 ///
79 /// [`Index`]: ../../std/ops/trait.Index.html
80 ///
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 /// ```
87 /// use std::ops::{Index,IndexMut};
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,
103 ///     pub right: Weight,
104 /// }
105 ///
106 /// impl Index<Side> for Balance {
107 ///     type Output = Weight;
108 ///
109 ///     fn index(&self, index: Side) -> &Self::Output {
110 ///         println!("Accessing {:?}-side of balance immutably", index);
111 ///         match index {
112 ///             Side::Left => &self.left,
113 ///             Side::Right => &self.right,
114 ///         }
115 ///     }
116 /// }
117 ///
118 /// impl IndexMut<Side> for Balance {
119 ///     fn index_mut(&mut self, index: Side) -> &mut Self::Output {
120 ///         println!("Accessing {:?}-side of balance mutably", index);
121 ///         match index {
122 ///             Side::Left => &mut self.left,
123 ///             Side::Right => &mut self.right,
124 ///         }
125 ///     }
126 /// }
127 ///
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);
142 /// ```
143 #[lang = "index_mut"]
144 #[rustc_on_unimplemented(
145     on(
146         _Self = "&str",
147         note = "you can use `.chars().nth()` or `.bytes().nth()`
148 see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
149     ),
150     on(
151         _Self = "str",
152         note = "you can use `.chars().nth()` or `.bytes().nth()`
153 see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
154     ),
155     on(
156         _Self = "std::string::String",
157         note = "you can use `.chars().nth()` or `.bytes().nth()`
158 see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
159     ),
160     message = "the type `{Self}` cannot be mutably indexed by `{Idx}`",
161     label = "`{Self}` cannot be mutably indexed by `{Idx}`"
162 )]
163 #[stable(feature = "rust1", since = "1.0.0")]
164 #[doc(alias = "[")]
165 #[doc(alias = "]")]
166 #[doc(alias = "[]")]
167 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
168     /// Performs the mutable indexing (`container[index]`) operation.
169     #[stable(feature = "rust1", since = "1.0.0")]
170     #[track_caller]
171     fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
172 }