Ejemplo
#[derive(Debug)] struct Race { name: String, laps: Vec<i32>, } impl Race { fn new(name: &str) -> Race { // No receiver, a static method Race { name: String::from(name), laps: Vec::new() } } fn add_lap(&mut self, lap: i32) { // Exclusive borrowed read-write access to self self.laps.push(lap); } fn print_laps(&self) { // Shared and read-only borrowed access to self println!("Recorded {} laps for {}:", self.laps.len(), self.name); for (idx, lap) in self.laps.iter().enumerate() { println!("Lap {idx}: {lap} sec"); } } fn finish(self) { // Exclusive ownership of self let total = self.laps.iter().sum::<i32>(); println!("Race {} is finished, total lap time: {}", self.name, total); } } fn main() { let mut race = Race::new("Monaco Grand Prix"); race.add_lap(70); race.add_lap(68); race.print_laps(); race.add_lap(71); race.print_laps(); race.finish(); // race.add_lap(42); }
Puntos Clave:
- Cada uno de estos cuatro métodos utilizan un receptor de método distinto.
- Puedes indicar cómo eso cambia lo que la función puede hacer con los valores de las variables y si se puede utilizar de nuevo en
main
y, en caso afirmativo, cómo. - Puedes mostrar el error que aparece al intentar llamar a
finish
dos veces.
- Puedes indicar cómo eso cambia lo que la función puede hacer con los valores de las variables y si se puede utilizar de nuevo en
- Ten en cuenta que, aunque los receptores de los métodos sean diferentes, las funciones no estáticas se llaman del mismo modo en el cuerpo principal. Rust habilita la referenciación y desreferenciación automáticas al llamar a los métodos. Además, añade automáticamente los caracteres
&
,*
ymuts
para que el objeto coincida con la firma del método. - Podrías mencionar que
print_laps
está usando un vector sobre el que se itera. Describiremos los vectores con más detalle por la tarde.