Ce face Index
v[i] este scurtătura pentru *v.index(i). Vec, tablourile, HashMap (doar citire) și String cu intervale (s[1..3]) implementează Index. Pentru tipurile tale îl implementezi alegând tipul indicelui (usize, &str, un enum) și tipul elementului (type Output).
index returnează o referință, nu o valoare, și nu are cum să returneze o eroare: prin convenție, un indice greșit oprește programul cu panică. Pentru un acces sigur oferă și o metodă get care returnează Option. Pentru scriere (c[i] = x) implementezi și IndexMut.
Parametri
| Parametru | Descriere |
|---|---|
type Output |
Tipul elementului returnat. |
index(&self, i) |
Returnează &Output pentru indicele dat. |
Ce returnează
&Self::Output (sau &mut pentru IndexMut).
Exemple
Exemplul 1: Catalog indexat după numele elevului
use std::ops::{Index, IndexMut};
struct Catalog {
elevi: Vec<(String, Vec<u8>)>,
}
impl Index<&str> for Catalog {
type Output = Vec<u8>;
fn index(&self, nume: &str) -> &Vec<u8> {
&self.elevi.iter().find(|(n, _)| n == nume).expect("elev inexistent").1
}
}
impl IndexMut<&str> for Catalog {
fn index_mut(&mut self, nume: &str) -> &mut Vec<u8> {
&mut self.elevi.iter_mut().find(|(n, _)| n == nume).expect("elev inexistent").1
}
}
fn main() {
let mut c = Catalog {
elevi: vec![("Ana".into(), vec![9, 10]), ("Radu".into(), vec![7])],
};
c["Radu"].push(9);
println!("Ana: {:?}", c["Ana"]);
println!("Radu: {:?}", c["Radu"]);
}
Rezultat
Ana: [9, 10]
Radu: [7, 9]
Exemplul 2: Indice de tip enum
use std::ops::Index;
#[derive(Clone, Copy)]
enum Zi {
Luni,
Marti,
Miercuri,
}
struct Program {
ore: [u8; 3],
}
impl Index<Zi> for Program {
type Output = u8;
fn index(&self, z: Zi) -> &u8 {
&self.ore[z as usize]
}
}
fn main() {
let p = Program { ore: [6, 5, 7] };
for (nume, zi) in [("luni", Zi::Luni), ("marți", Zi::Marti), ("miercuri", Zi::Miercuri)] {
println!("{nume}: {} ore", p[zi]);
}
}
Rezultat
luni: 6 ore
marți: 5 ore
miercuri: 7 ore
Greșeli frecvente
- Încerci
c[i] = xcu doarIndeximplementat:cannot assign to data in an index of `Catalog`. Implementează șiIndexMut. - Returnezi o valoare în loc de referință din
index: semnătura cere&Self::Output.
Comenzi înrudite
Add: Trait-ul din spatele operatorului +; implementându-l, poți aduna valori ale tipurilor tale (bani, vectori).Deref: Trait-ul din spatele operatorului * și al conversiei automate &Box<T> -> &T, &String -> &str (deref coercion).str: Tipul pentru o bucată de text UTF-8 împrumutată (&str): literalii, părți din String, parametrii de funcții.