试图编译这个程序我被困在借阅检查器上:
use std::collections::BTreeMap;
type Object<'a> = BTreeMap<&'a str, i32>;
struct Root<'a>(Object<'a>);
struct Sub<'a>(&'a mut Object<'a>, &'a str);
impl<'a> Root<'a> {
fn borrow_mut(&'a mut self, data: &'a str) -> Sub<'a> {
Sub(&mut self.0, data)
}
fn borrow(&self) {
println!("{:?}", self.0);
}
}
fn main() {
let mut me = Root(Object::new());
{
me.borrow_mut("data!");
}
me.borrow();
}
Run Code Online (Sandbox Code Playgroud)
(游乐场)
我明白了:
error[E0502]: cannot borrow `me` as immutable because it is also borrowed as mutable
--> src/main.rs:24:5
|
22 | me.borrow_mut("data!");
| -- mutable borrow occurs here
23 | }
24 | me.borrow();
| ^^ immutable borrow occurs here
25 | }
| - mutable borrow ends here
Run Code Online (Sandbox Code Playgroud)
看起来可变借款应该在此之前结束,me.borrow()但借款检查员坚持认为它在结束时main结束.
要快速解释我想要实现的目标:
你正在与一生的问题发生冲突.
您的计划中有多个不同的生命周期:
type Object<'a> = BTreeMap<&'a str, i32>; =>这是一个&'a mut Object<'a> =>这里最多有两个struct Sub<'a>(&'a mut Object<'a>, &'a str); =>这里有三个显然,没有理由提到Object<'a>具有与&str内部相同的寿命BTreeMap.但是,你告诉编译器你希望两个生命周期都一样!
当你写:
struct Sub<'a>(&'a mut Object<'a>, &'a str);
Run Code Online (Sandbox Code Playgroud)
你告诉编译器:
&str内心的生命BTreeMapObject<'_>&str陪伴的生命Object<'_>都是一样的.
你过度约束了这些要求; 因此,没有解决方案可以满足他们.
增加一个自由度就足够了!我们只是将引用Object<'_>的生命周期与&str浮动周期的生命周期不同:
struct Sub<'a, 'b: 'a>(&'a mut Object<'b>, &'b str);
impl<'b> Root<'b> {
fn borrow_mut<'a>(&'a mut self, data: &'b str) -> Sub<'a, 'b> {
Sub(&mut self.0, data)
}
fn borrow(&self) {
println!("{:?}", self.0);
}
}
Run Code Online (Sandbox Code Playgroud)
注意微妙'b: 'a:
Object<'b> 包含对其生命周期为的内容的引用 'bObject<'b>(表示'a)的引用的生命周期必须比'b(或者你有一些死的引用?)因此,我们说'b会超越'a使用'b: 'a.
就是这样.简单地放宽要求允许编译器允许您的代码进行编译.
请注意,一般情况下,如果你发现自己写的东西就像&'a &'a str你做错了.如果你仔细想想,你会发现,为了创造的东西的引用,首先必须是.因此,对象的引用必然比对象本身具有更短的生命周期(如此轻微).