// 在manager字段中对于第一个'a它是协变的, 对于第二个'a, 由于mut的原因, Manager<'a>是不变的, 所以'a是不变的,因此整体是不变的
struct Interface<'a> {
manager: &'a mut Manager<'a>,
}
impl<'a> Interface<'a> {
pub fn noop(self) {
println!("interface consumed");
}
}
// 在text字段中'a是协变的, 因此Manager对于'a是协变的
struct Manager<'a> {
text: &'a str,
}
// 同理对于List来说, 在'a上是协变的
struct List<'a> {
manager: Manager<'a>,
}
impl<'a> List<'a> {
// 这个方法由于Interface对其生命周期参数是不变的, 导致'a是不变的, 又由于'a与List绑定, 导致对List的&mut(可变借用)会与List本身一致
pub fn get_interface(&'a mut self) -> Interface<'a> {
Interface {
manager: &mut self.manager,
}
}
}
fn main() {
let mut list = List {
manager: Manager { text: "hello" },
};
// 按道理来说这里返回的匿名Interface应该会在这一行后直接被drop掉, 因此list也应该被drop掉(见get_interface注释)
// 但是实际上下面的use_list(&list)的报错是list被可变借用了, 不能再被借用
// 因此我是否可以认为这个那个逆名的Interface没有被dro掉, 它保持到了use_list(&list)的结束
list.get_interface().noop();
println!("Interface should be dropped here and the borrow released");
use_list(&list);
}
fn use_list(list: &List) {
println!("{}", list.manager.text);
}
这个理解是否正确, 请佬教一下我
1
共 6 条评论, 1 页
评论区
写评论看到这个想起来之前也有个类似的讨论:sqlx生命周期问题
感谢
--
👇
zylthinking: 借用检查是编译期分析, 它看到的是源代码, 不会关心运行; 你告诉它 'a 它就在代码里面圈定 'a 的范围; 然后检查这个范围内有没有违反借用规则的语句.
大概就这么理解就行
借用检查是编译期分析, 它看到的是源代码, 不会关心运行; 你告诉它 'a 它就在代码里面圈定 'a 的范围; 然后检查这个范围内有没有违反借用规则的语句.
大概就这么理解就行
确实是一样的效果,那就是&'a mut self已经表明了这个可变引用的生命周期与List<'a>一致, 即使是get_interface(&'a mut self)->()调用完成后可以释放掉了, rust的借用检查器也不会释放掉可变引用对吗
--
👇
zylthinking: ``` pub fn get_interface(&'a mut self) -> Interface<'a>
pub fn get_interface(&'a mut self) -> ()
这里其实和返回的 Interface<'a> 没啥关系 &'a mut self 已经表明了存在一个对 List<'a> 的引用, 它的生命周期持续到 'a 结束; 而 List<'a> 也不可能超过 'a 而存在; 因此, 这基本表明了 &'a mut self 创建出来后, 就别想着直接访问 List<'a> 了
你可以试试这个
估计一样的效果, 如果我理解没有错误的话
有佬告诉我说, 这个形变不会影响那个匿名Interface何时被drop, 那么是不是即使被drop掉了, 在借用检查器中, 可变借用依然存在, 所以编辑器才会报可变借用和借用同时存在的问题