如何解决不能借用可变的问题,因为它位于“&”引用后面

2 rust

我是 Rust 新手,正在尝试学习和实验,这里是游乐场的链接,其中包含以下问题和解释:https: //play.rust-lang.org/ ?version=stable&mode=debug&edition=2018&gist=19920813410a42500045cf2c6cc94f12

use std::fmt;

#[derive(Clone, Copy)]
struct Animal<'a> {
    name: &'a str
}

impl <'a>Animal<'a> {
    fn new(name: &'a str) ->  Self { Self { name } }    
}
struct Barn<'a> {
    name: &'a str,
    animals: Vec<Animal<'a>>
}

impl <'a> Barn<'a> {
    fn new(name: &'a str, animals: Vec<Animal<'a>>) ->  Self { Self { name, animals } }    
}

impl <'a>fmt::Debug for Barn<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.name)
    }
}

struct Farmer<'a> {
    name: &'a str,
    barns: Vec<Barn<'a>>
}

impl <'a> Farmer<'a> {
    fn new(name: &'a str, barns: Vec<Barn<'a>>) -> Self { Self { name, barns } }
    
    fn add_new_barn(&mut self, barn: Barn<'a>) {
        self.barns.push(barn)
    }
    
    fn place_animal_in_barn(&mut self, animal: Animal, placement: &str) {
        for barn in &self.barns {
            // how do I do make this work?
            if barn.name == placement {
                barn.animals.push(animal);
            }
        }
    }
}

impl <'a>fmt::Debug for Farmer<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:#?}", self.barns)
    }
}

fn main() {
    let mut farmer = Farmer::new("Farm Master Joe",
        vec![
            Barn::new("Tegridy Farms", vec![
                Animal::new("cow"), 
                Animal::new("horse"), 
                Animal::new("pigeon")
            ]), 
            Barn::new("Barney", vec![
                Animal::new("Purple Dinosaur"), 
                Animal::new("Green Dinosaur")
            ]), 
            Barn::new("White Rabbits R' Us", vec![
                Animal::new("white rabbit"),
            ])
        ]
    );
    
    println!("{:#?}", farmer.name);
    farmer.add_new_barn(Barn::new("The Good Place", vec![
        Animal::new("Horse"),
        Animal::new("Wombat")
    ]));
    
    farmer.place_animal_in_barn(Animal::new("Turkey"), "The Good Place");
    println!("{:#?}", farmer);
}
Run Code Online (Sandbox Code Playgroud)

我该如何修复这个方法,以便我可以推送到向量?

    fn place_animal_in_barn(&mut self, animal: Animal, placement: &str) {
        for barn in &self.barns {
            // how do I do make this work?
            if barn.name == placement {
                barn.animals.push(animal);
            }
        }
    }

Run Code Online (Sandbox Code Playgroud)

我收到以下错误,但我不太明白它或如何修复它:

  |
39 |         for barn in &self.barns {
   |                     ----------- this iterator yields `&` references
...
42 |                 barn.animals.push(animal);
   |                 ^^^^^^^^^^^^ `barn` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Run Code Online (Sandbox Code Playgroud)

小智 5

在阅读了 for 循环中的可变借用之后,看起来这就是解决方案:

    fn place_animal_in_barn(&mut self, animal: Animal<'a>, placement: &str) {
        for barn in &mut self.barns {
            if barn.name == placement {
                barn.animals.push(animal);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

链接到游乐场:https://play.rust-lang.org/? version=stable&mode=debug&edition=2018&gist=1ad9443801991ed12c6c112d78104cfa