这是一个概念性的问题,但此代码不编译:

struct HashHolder{
    pub thing: HashMap<usize, usize>,
}
impl HashHolder {
    fn insert(&mut self, item: &usize) {
        let test = self.thing.get(item).clone(); // immutable borrow occurs here
        for i in 0..10 {
            match test { // immutable borrow later used here
                Some(t) => {
                    //nothing
                },
                None => {
                    self.thing.insert(0, item.clone()); // mutable borrow occurs here
                }
            }
        }
    }
}

它给出了"error[E0502]:不能将self.thing作为可变项borrow ,因为它也是作为不可变项borrow 的",并突出显示了上面显示的行.

然而,如果我go 掉for循环,它编译得很好!对我来说,这样的编译应该不会有任何问题:match的范围在循环的每次迭代中都会结束,所以所有引用都应该是" fresh 的".如果我删除循环并再次复制粘贴match块,也会产生相同的错误.

我对参考/borrow 的理解是:

  1. self是永久borrow 的self.thing.get(item).但在clone()之后,它应该释放那笔借款吗?
  2. selfself.thing.insert(...);处可变borrow ,但一旦insert完成执行,该borrow 也应被释放.

所以我不明白为什么会发生这种错误.此外,编译器突出显示的行是无用的,因为这三行without the for loop完全可以!

在我对这段代码中发生的事情的理解上有什么错误吗?如果我想多次匹配,什么样的 struct 会更好?

这种方法的部分原因是,在我的实际项目中,test的值在循环中会有所不同,并且在某些情况下可以给定一个值,因此match在不同的迭代中可能表现不同.也许这不是实现我想要的行为的最佳方法,但我仍然想理解为什么它甚至无法编译.

推荐答案

self.thing.get(item)返回Option<&usize>类型的值,该值保存对self.thing的引用.克隆此值时,只克隆Option,而得到另一个Option<&usize>,它仍然保留对self.thing的引用.如果你想得到一个拥有的值,你需要用Option::cloned(或者Option::copied,因为usizeCopy)来克隆内部值,这会给你一个Option<usize>.

Rust相关问答推荐

捕获Rust因C++异常而产生panic

在Tauri中获取ICoreWebView 2_7以打印PDF

为什么拥有的trait对象的相等运算符移动了正确的操作数?

在不重写/专门化整个函数的情况下添加单个匹配手臂到特征的方法?

从未排序的链表中删除重复项的铁 rust 代码在ELSE分支的低级上做了什么?

零拷贝按步骤引用一段字节

将Vec<;U8&>转换为Vec<;{Float}&>

应为关联类型,找到类型参数

通过异常从同步代码中产生yield 是如何工作的?

Rust proc_macro 和 syn:解析空格

一旦令牌作为文字使用,声明宏不匹配硬编码值?

pyO3 和 Panics

在给定 Rust 谓词的情况下,将 Some 转换为 None 的惯用方法是什么?

有没有办法通过命令获取 Rust crate 的可安装版本列表?

Rust 函数指针似乎被borrow 判断器视为有状态的

没有分号的返回表达式的性能是否比使用返回更好?在Rust ?

如何为返回正确类型的枚举实现 get 方法?

如何创建动态创建值并向它们返回borrow 的工厂?

A 有一个函数,它在 Option<> 类型中时无法编译,但在 Option<> 类型之外会自行编译.为什么?

list 中没有指定目标 - 必须存在 src/lib.rs、src/main.rs、[lib] 部分或 [[bin]] 部分