index.rs - source
Description: Source of the Rust file `library/core/src/ops/index.rs`.
Keywords: rust, rustlang, rust-lang

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167

    /// Used for indexing operations (`container[index]`) in immutable contexts.
    ///
    /// `container[index]` is actually syntactic sugar for `*container.index(index)`,
    /// but only when used as an immutable value. If a mutable value is requested,
    /// [`IndexMut`] is used instead. This allows nice things such as
    /// `let value = v[index]` if the type of `value` implements [`Copy`].
    ///
    /// # Examples
    ///
    /// The following example implements `Index` on a read-only `NucleotideCount`
    /// container, enabling individual counts to be retrieved with index syntax.
    ///
    /// ```
    /// use std::ops::Index;
    ///
    /// enum Nucleotide {
    ///     A,
    ///     C,
    ///     G,
    ///     T,
    /// }
    ///
    /// struct NucleotideCount {
    ///     a: usize,
    ///     c: usize,
    ///     g: usize,
    ///     t: usize,
    /// }
    ///
    /// impl Index<Nucleotide> for NucleotideCount {
    ///     type Output = usize;
    ///
    ///     fn index(&self, nucleotide: Nucleotide) -> &Self::Output {
    ///         match nucleotide {
    ///             Nucleotide::A => &self.a,
    ///             Nucleotide::C => &self.c,
    ///             Nucleotide::G => &self.g,
    ///             Nucleotide::T => &self.t,
    ///         }
    ///     }
    /// }
    ///
    /// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12};
    /// assert_eq!(nucleotide_count[Nucleotide::A], 14);
    /// assert_eq!(nucleotide_count[Nucleotide::C], 9);
    /// assert_eq!(nucleotide_count[Nucleotide::G], 10);
    /// assert_eq!(nucleotide_count[Nucleotide::T], 12);
    /// ```
    #[lang = "index"]
    #[rustc_on_unimplemented(
        message = "the type `{Self}` cannot be indexed by `{Idx}`",
        label = "`{Self}` cannot be indexed by `{Idx}`"
    )]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[doc(alias = "]")]
    #[doc(alias = "[")]
    #[doc(alias = "[]")]
    pub trait Index<Idx: ?Sized> {
        /// The returned type after indexing.
        #[stable(feature = "rust1", since = "1.0.0")]
        type Output: ?Sized;

        /// Performs the indexing (`container[index]`) operation.
        #[stable(feature = "rust1", since = "1.0.0")]
        #[track_caller]
        fn index(&self, index: Idx) -> &Self::Output;
    }

    /// Used for indexing operations (`container[index]`) in mutable contexts.
    ///
    /// `container[index]` is actually syntactic sugar for
    /// `*container.index_mut(index)`, but only when used as a mutable value. If
    /// an immutable value is requested, the [`Index`] trait is used instead. This
    /// allows nice things such as `v[index] = value`.
    ///
    /// # Examples
    ///
    /// A very simple implementation of a `Balance` struct that has two sides, where
    /// each can be indexed mutably and immutably.
    ///
    /// ```
    /// use std::ops::{Index,IndexMut};
    ///
    /// #[derive(Debug)]
    /// enum Side {
    ///     Left,
    ///     Right,
    /// }
    ///
    /// #[derive(Debug, PartialEq)]
    /// enum Weight {
    ///     Kilogram(f32),
    ///     Pound(f32),
    /// }
    ///
    /// struct Balance {
    ///     pub left: Weight,
    ///     pub right: Weight,
    /// }
    ///
    /// impl Index<Side> for Balance {
    ///     type Output = Weight;
    ///
    ///     fn index(&self, index: Side) -> &Self::Output {
    ///         println!("Accessing {:?}-side of balance immutably", index);
    ///         match index {
    ///             Side::Left => &self.left,
    ///             Side::Right => &self.right,
    ///         }
    ///     }
    /// }
    ///
    /// impl IndexMut<Side> for Balance {
    ///     fn index_mut(&mut self, index: Side) -> &mut Self::Output {
    ///         println!("Accessing {:?}-side of balance mutably", index);
    ///         match index {
    ///             Side::Left => &mut self.left,
    ///             Side::Right => &mut self.right,
    ///         }
    ///     }
    /// }
    ///
    /// let mut balance = Balance {
    ///     right: Weight::Kilogram(2.5),
    ///     left: Weight::Pound(1.5),
    /// };
    ///
    /// // In this case, `balance[Side::Right]` is sugar for
    /// // `*balance.index(Side::Right)`, since we are only *reading*
    /// // `balance[Side::Right]`, not writing it.
    /// assert_eq!(balance[Side::Right], Weight::Kilogram(2.5));
    ///
    /// // However, in this case `balance[Side::Left]` is sugar for
    /// // `*balance.index_mut(Side::Left)`, since we are writing
    /// // `balance[Side::Left]`.
    /// balance[Side::Left] = Weight::Kilogram(3.0);
    /// ```
    #[lang = "index_mut"]
    #[rustc_on_unimplemented(
        on(
            _Self = "&str",
            note = "you can use `.chars().nth()` or `.bytes().nth()`
    see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
        ),
        on(
            _Self = "str",
            note = "you can use `.chars().nth()` or `.bytes().nth()`
    see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
        ),
        on(
            _Self = "std::string::String",
            note = "you can use `.chars().nth()` or `.bytes().nth()`
    see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
        ),
        message = "the type `{Self}` cannot be mutably indexed by `{Idx}`",
        label = "`{Self}` cannot be mutably indexed by `{Idx}`"
    )]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[doc(alias = "[")]
    #[doc(alias = "]")]
    #[doc(alias = "[]")]
    pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
        /// Performs the mutable indexing (`container[index]`) operation.
        #[stable(feature = "rust1", since = "1.0.0")]
        #[track_caller]
        fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
    }