Rust 推送到带有 borrow_mut 的矢量

Rust pushing to vector with borrow_mut

提问人:Filip Čermák 提问时间:12/1/2022 最后编辑:Filip Čermák 更新时间:12/1/2022 访问量:225

问:

让我们有一个包含城市向量的结构体和一个将城市添加到向量的new_city函数。但是,我得到了 BorrowMutError,这是有道理的。

我应该怎么做才能多次打电话给new_city(见下文)? 我需要在new_city函数中删除borrow_mut引用,但我不知道该怎么做。

//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);    

}

编辑:下次使用

然后我需要 prg 和 brn 城市使用 API(模拟中的另一个向量)添加它们之间的道路

pub fn new_road(&self, from: &City, to: &City, time: i32) -> &Road {
         //Adding information about road to simulation
}

let d1 = simulation.new_road(&prg, &brn, 120);

因此,我不能放弃 prg 或 brn。

可变 借用检查器 参考电池

评论

0赞 Deadbeef 12/1/2022
你应该使用 ,而不是 。Vec<RefCell<City>>RefCell<Vec<City>>
0赞 cafce25 12/1/2022
@Deadbeef如果他们必须修改Vec

答:

0赞 cafce25 12/1/2022 #1

您可以简单地引入一个新范围,在该范围结束时删除:BorrowMut

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())
}

但是你也不能在通话中保持 s。Refnew_city

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

您可能希望将城市包装在 s 中,以便能够在 es 中保留它们:Rcpush

pub struct Simulation{
    cities: RefCell<Vec<Rc<City>>>,
}
//...
impl Simulation {
    //...
    pub fn new_city(&self, name: &'static str) -> Rc<City> { 
        {
            let city = Rc::new(City::new(name));
            self.cities.borrow_mut().push(city);
        }

        self.cities.borrow().last().unwrap().clone()
    }
}

评论

0赞 Filip Čermák 12/1/2022
这无济于事,因为编译器仍然返回线程“main”,对“已经借用:BorrowMutError”感到恐慌。但是谢谢。
0赞 cafce25 12/1/2022
@FilipČermák 请参阅编辑。 ing 到 a 可能会移动其中的所有元素,因此您无法跨调用保留引用。pushVecpush
0赞 Filip Čermák 12/1/2022
谢谢,我添加了代码的下一部分(编辑后:在最后),以确保即使我应该删除 prg 或 brn,我也无法删除。我看到我需要删除它,但我仍然需要一个包含城市和道路的结构模拟。
0赞 cafce25 12/1/2022
@FilipČermák 再次编辑,但现在是 为什么我不能在同一结构中存储值和对该值的引用? IMO。