【问题标题】:Rust pushing to vector with borrow_mutRust pushing to vector with borrow_mut
【发布时间】:2022-12-01 22:40:25
【问题描述】:

Let's have a struct containing a vector of cities and a new_city function adding City to the vector. However, I got BorrowMutError which makes sense.

What should I do so I can call new_city multiple times (see below)? I would need to drop the borrow_mut reference in the new_city function but I don't know how.

//use std::rc::Rc;
use std::cell::RefCell;
use std::cell::Ref;

pub struct Simulation{
    cities: RefCell<Vec<City> >,
}


impl Simulation{

    pub fn new() -> Simulation
    {
        Simulation{
            cities: RefCell::new(Vec::new()),
        }
    }

    pub fn new_city(&self, name: &'static str) -> Ref<City> { 
        let city = City::new(name);
        self.cities.borrow_mut().push(city);

        Ref::map(self.cities.borrow(), |vec| vec.last().unwrap())
    }

}

#[derive(Debug, Copy, Clone)]
pub struct City {
    name: &'static str,
}

impl City{
    pub fn new(name: &'static str) -> City {
        City { name: name, }
    }
}

fn main(){

    let mut simulation = Simulation::new();

    let prg = simulation.new_city("Prague");
    let brn = simulation.new_city("Brno");
    let pls = simulation.new_city("Pilsen");


    println!("{:?}", prg);    

}

【问题讨论】:

  • You should use Vec&lt;RefCell&lt;City&gt;&gt;, not RefCell&lt;Vec&lt;City&gt;&gt;.
  • @Deadbeef that doesn't help much if they have to modify the Vec

标签: rust mutable borrow-checker refcell


【解决方案1】:

You could simply introduce a new scope at the end of which the BorrowMut gets dropped:

pub fn new_city(&self, name: &'static str) -> Ref<City> {
    {
        let city = City::new(name);
        self.cities.borrow_mut().push(city);
    }
    Ref::map(self.cities.borrow(), |vec| vec.last().unwrap())
}

But you can't hold on to the Refs across new_city calls either.

fn main() {
    let mut simulation = Simulation::new();
    let prg = simulation.new_city("Prague");
    drop(prg);
    let brn = simulation.new_city("Brno");
}

【讨论】:

  • This didn't help as the compiler still returns thread 'main' panicked at 'already borrowed: BorrowMutError'. But thanks.
  • @FilipČermák See the edit. pushing to a Vec might move all elements in it, thus you can't hold on to references across push calls.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-20
  • 2022-12-04
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
相关资源
最近更新 更多