Translate

viernes, 1 de septiembre de 2023

Metodos en Rust parte 3


Veamos un ejemplo de metodos:

#[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);

}

Lo ejecutamos : 

cargo run

   Compiling hello_cargo v0.1.0 

     Finished dev [unoptimized + debuginfo] target(s) in 0.62s

     Running `target/debug/hello_cargo`

Recorded 2 laps for Monaco Grand Prix:

Lap 0: 70 sec

Lap 1: 68 sec

Recorded 3 laps for Monaco Grand Prix:

Lap 0: 70 sec

Lap 1: 68 sec

Lap 2: 71 sec

Race Monaco Grand Prix is finished, total lap time: 209


Los cuatro métodos aquí utilizan un receptor de método diferente.

Si intentamos llamar a finalizar dos veces o descomentamos // race.add_lap(42); , lanza este error : 

cargo run

   Compiling hello_cargo v0.1.0 

error[E0382]: borrow of moved value: `race`

  --> src/main.rs:37:5

   |

30 |     let mut race = Race::new("Monaco Grand Prix");

   |         -------- move occurs because `race` has type `Race`, which does not implement the `Copy` trait

...

36 |     race.finish();

   |          -------- `race` moved due to this method call

37 |     race.add_lap(42);

   |     ^^^^^^^^^^^^^^^^ value borrowed here after move

   |

note: this function takes ownership of the receiver `self`, which moves `race`

  --> src/main.rs:23:15

   |

23 |     fn finish(self) {  // Exclusive ownership of self

   |               ^^^^

For more information about this error, try `rustc --explain E0382`.

error: could not compile `hello_cargo` due to previous error

Y es porque finish toma todo el control del registro. 

Tenga en cuenta que, aunque los receptores de métodos son diferentes, las funciones no estáticas se denominan de la misma manera en el cuerpo principal. Rust permite la referencia y desreferenciación automática al llamar a métodos. Rust agrega automáticamente los cambios &, *, para que ese objeto coincida con la firma del método.