在同一选项上不止一次匹配会产生太多的自我引用
这是一个概念上的问题,但是此代码没有编译:
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
是可变的,因为它也被借用为不可变动”,并突出显示了行如上所示。
但是,如果我为循环取出,它可以很好地编译!在我看来,这应该在没有问题的情况下进行编译:
匹配的范围
在循环的每个迭代中结束,因此所有参考都应“新鲜”。如果我删除循环并将匹配
第二次封锁,则可以产生相同的错误。
我对引用/借用的理解是:
self
是无价借来的self.thing.get(item)
。但是,在clone()
之后,它应该释放借用?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:
self
is immutably borrowedself.thing.get(item)
. But after theclone()
, it should release that borrow?self
is mutably borrowed atself.thing.insert(...);
but onceinsert
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
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 typeOption<&usize>
which holds a reference toself.thing
. When you clone this value, you only clone theOption
and you get anotherOption<&usize>
which still holds a reference toself.thing
. If you want to get an owned value, you need to clone the inner value withOption::cloned
(orOption::copied
sinceusize
areCopy
) which will give you anOption<usize>
.