use std::collections::HashMap;
use std::collections::hash_map::Entry::*;
struct A {
    map: HashMap<String, String>,
    i: i32
}
impl A {
    fn test(&mut self) {
        match self.map.get("abc") {
            None => {},
            Some(x) => self.trigger(&x)
        }
    }
    fn trigger(&mut self, x: &str) {
        self.i += 1;
    }
}
该代码不起作用,因为可变self.trigger借用self,同时在范围内self.map.get保持不可变借用self。
鉴于我可以确保不trigger修改,有什么方法可以使其工作吗self.map?
我不能一成不变地trigger借用self,就像  我可以为 self.callbacks: Vec<Box<FnMut>>? 一样借用 self 吗?
我正在使用 rustc 1.19.0-nightly。
小智 5
这里的问题是借用检查器不知道trigger仅发生变化self.i。据借用检查员所知,它也可能会改变self.map,这是不安全的。
解决方案是告诉借用检查员更多有关trigger更改的信息。
实现此目的的一种方法是将trigger需要可变借用的所有内容移至其自己的结构中,然后为该结构实现触发器:
use std::collections::HashMap;
use std::collections::hash_map::Entry::*;
struct TriggerThing {
    i: i32
}
impl TriggerThing {
    fn trigger(&mut self, _: &HashMap<String, String>, x: &str) {
        self.i += 1;
    }
}
struct A {
    map: HashMap<String, String>,
    trigger_thing: TriggerThing,
}
impl A {
    fn test(&mut self) {
        // Its fine to have a immutable borrow of self.map
        // and a mutable borrow of self.trigger_thing at the
        // same time, since borrowing self.trigger_thing does not
        // imply a mutable borrow of self.map.
        if let Some(x) = self.map.get("abc") {
            // Notice that we can still give self.trigger_thing
            // access to self.map, as long as we only
            // give it an immutable reference
            self.trigger_thing.trigger(&self.map, &x)
        }
    }
}
如果您之前没有见过它的精彩语法,请参阅《Rust Book: If Let》 。if let
| 归档时间: | 
 | 
| 查看次数: | 1532 次 | 
| 最近记录: |