index.rs - source
Description: Source of the Rust file `library/core/src/ops/index.rs`.

#
core/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/// # 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///
    33///     fn index(&self, nucleotide: Nucleotide) -> &Self::Output {
    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"]
    50#[diagnostic::on_unimplemented(
    51    message = "the type `{Self}` cannot be indexed by `{Idx}`",
    52    label = "`{Self}` cannot be indexed by `{Idx}`"
    53)]
    54#[stable(feature = "rust1", since = "1.0.0")]
    55#[doc(alias = "]")]
    56#[doc(alias = "[")]
    57#[doc(alias = "[]")]
    58#[rustc_const_unstable(feature = "const_index", issue = "143775")]
    59pub const trait Index<Idx: ?Sized> {
    60    /// The returned type after indexing.
    61    #[stable(feature = "rust1", since = "1.0.0")]
    62    #[rustc_diagnostic_item = "IndexOutput"]
    63    type Output: ?Sized;
    64
    65    /// Performs the indexing (`container[index]`) operation.
    66    ///
    67    /// # Panics
    68    ///
    69    /// May panic if the index is out of bounds.
    70    #[stable(feature = "rust1", since = "1.0.0")]
    71    #[rustc_no_implicit_autorefs]
    72    #[track_caller]
    73    fn index(&self, index: Idx) -> &Self::Output;
    74}
    75
    76/// Used for indexing operations (`container[index]`) in mutable contexts.
    77///
    78/// `container[index]` is actually syntactic sugar for
    79/// `*container.index_mut(index)`, but only when used as a mutable value. If
    80/// an immutable value is requested, the [`Index`] trait is used instead. This
    81/// allows nice things such as `v[index] = value`.
    82///
    83/// # Examples
    84///
    85/// A very simple implementation of a `Balance` struct that has two sides, where
    86/// each can be indexed mutably and immutably.
    87///
    88/// ```
    89/// use std::ops::{Index, IndexMut};
    90///
    91/// #[derive(Debug)]
    92/// enum Side {
    93///     Left,
    94///     Right,
    95/// }
    96///
    97/// #[derive(Debug, PartialEq)]
    98/// enum Weight {
    99///     Kilogram(f32),
    100///     Pound(f32),
    101/// }
    102///
    103/// struct Balance {
    104///     pub left: Weight,
    105///     pub right: Weight,
    106/// }
    107///
    108/// impl Index<Side> for Balance {
    109///     type Output = Weight;
    110///
    111///     fn index(&self, index: Side) -> &Self::Output {
    112///         println!("Accessing {index:?}-side of balance immutably");
    113///         match index {
    114///             Side::Left => &self.left,
    115///             Side::Right => &self.right,
    116///         }
    117///     }
    118/// }
    119///
    120/// impl IndexMut<Side> for Balance {
    121///     fn index_mut(&mut self, index: Side) -> &mut Self::Output {
    122///         println!("Accessing {index:?}-side of balance mutably");
    123///         match index {
    124///             Side::Left => &mut self.left,
    125///             Side::Right => &mut self.right,
    126///         }
    127///     }
    128/// }
    129///
    130/// let mut balance = Balance {
    131///     right: Weight::Kilogram(2.5),
    132///     left: Weight::Pound(1.5),
    133/// };
    134///
    135/// // In this case, `balance[Side::Right]` is sugar for
    136/// // `*balance.index(Side::Right)`, since we are only *reading*
    137/// // `balance[Side::Right]`, not writing it.
    138/// assert_eq!(balance[Side::Right], Weight::Kilogram(2.5));
    139///
    140/// // However, in this case `balance[Side::Left]` is sugar for
    141/// // `*balance.index_mut(Side::Left)`, since we are writing
    142/// // `balance[Side::Left]`.
    143/// balance[Side::Left] = Weight::Kilogram(3.0);
    144/// ```
    145#[lang = "index_mut"]
    146#[rustc_on_unimplemented(
    147    on(
    148        Self = "&str",
    149        note = "you can use `.chars().nth()` or `.bytes().nth()`
    150see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
    151    ),
    152    on(
    153        Self = "str",
    154        note = "you can use `.chars().nth()` or `.bytes().nth()`
    155see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
    156    ),
    157    on(
    158        Self = "alloc::string::String",
    159        note = "you can use `.chars().nth()` or `.bytes().nth()`
    160see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
    161    ),
    162    message = "the type `{Self}` cannot be mutably indexed by `{Idx}`",
    163    label = "`{Self}` cannot be mutably indexed by `{Idx}`"
    164)]
    165#[stable(feature = "rust1", since = "1.0.0")]
    166#[doc(alias = "[")]
    167#[doc(alias = "]")]
    168#[doc(alias = "[]")]
    169#[rustc_const_unstable(feature = "const_index", issue = "143775")]
    170pub const trait IndexMut<Idx: ?Sized>: [const] Index<Idx> {
    171    /// Performs the mutable indexing (`container[index]`) operation.
    172    ///
    173    /// # Panics
    174    ///
    175    /// May panic if the index is out of bounds.
    176    #[stable(feature = "rust1", since = "1.0.0")]
    177    #[rustc_no_implicit_autorefs]
    178    #[track_caller]
    179    fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
    180}