在同一选项上不止一次匹配会产生太多的自我引用

发布于 2025-02-09 03:04:11 字数 1352 浏览 1 评论 0原文

这是一个概念上的问题,但是此代码没有编译:

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

它给出了“错误[E0502]:不能借用self.thing是可变的,因为它也被借用为不可变动”,并突出显示了行如上所示。

但是,如果我为循环取出,它可以很好地编译!在我看来,这应该在没有问题的情况下进行编译:匹配的范围在循环的每个迭代中结束,因此所有参考都应“新鲜”。如果我删除循环并将匹配第二次封锁,则可以产生相同的错误。

我对引用/借用的理解是:

  1. self是无价借来的self.thing.get(item)。但是,在clone()之后,它应该释放借用?
  2. self是在self.thing.thing.insert(...);上可被借来的,但是一旦插入完成执行,也应发布该借款。

所以我不明白为什么会发生此错误。此外,编译器的亮点是没有用的,因为这三行( 没有for循环)完全很好!

在理解此代码中发生的事情时,我有什么问题吗?如果我想多次匹配,那将是更好的结构?

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

This is sort of a conceptual question, but this code does not compile:

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

It gives "error[E0502]: cannot borrow self.thing as mutable because it is also borrowed as immutable", and highlights the lines shown above.

However, if I take out the for loop, it compiles just fine! It feels to me like this should compile without issue either way: the scope of the match ends within each iteration of the loop, so all the references should be "fresh". The same error can be produced if I remove the loop and just copy-paste the match block a second time.

My understanding of the referencing/borrowing is:

  1. self is immutably borrowed self.thing.get(item). But after the clone(), it should release that borrow?
  2. self is mutably borrowed at self.thing.insert(...); but once insert finishes execution, that borrow should also be released.

So I don't understand why this error occurs. Moreover, the lines the compiler highlights are useless, since those three lines, without the for loop, are completely fine!

Is there anything I'm wrong about in my understanding of what's happening in this code, and what would be a better structure if I want to match multiple times?

Part of the reason for this approach is that in my actual project, the value of test will vary through the loop and can be given a value in certain cases, so the match might behave differently in different iterations. Maybe this isn't the best approach for the behaviour I want, but I'd still like to understand why it won't even compile.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

幸福还没到 2025-02-16 03:04:11

self.thing.get(item)返回一个类型option&lt;&amp; usize&gt;的值,该值包含self.thing的引用。当您克隆此值时,只需克隆option,然后将获得另一个option&lt;&amp; usize&gt;仍然具有self.thing。如果您想获得一个自有的值,则需要用 option ::克隆 (或 option ::复制因为usize usize复制)将为您提供选项&lt; usize&gt;

self.thing.get(item) returns a value of type Option<&usize> which holds a reference to self.thing. When you clone this value, you only clone the Option and you get another Option<&usize> which still holds a reference to self.thing. If you want to get an owned value, you need to clone the inner value with Option::cloned (or Option::copied since usize are Copy) which will give you an Option<usize>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文