关于Rust中Option::take()返回引用匹配生命周期'a的疑惑
Rust中Option::take()与生命周期
'a的疑问解答 原错误代码
struct Node<T>(T); struct Wrapper<'a, T: 'a>(&'a mut Node<T>); impl<'a, T: 'a> Wrapper<'a, T> { // error: lifetime may not live long enough fn func(&mut self) -> &'a mut T { &mut self.0 .0 } }
修复后的代码
struct Wrapper<'a, T: 'a>(Option<&'a mut Node<T>>); impl<'a, T: 'a> Wrapper<'a, T> { fn func(&mut self) -> &'a mut T { // Option::take() let node = self.0.take().unwrap(); &mut node.0 } }
疑问解答
先讲原代码报错的核心原因:Wrapper持有的是&'a mut Node<T>类型的引用,当调用func(&mut self)时,self的临时生命周期'b必然短于'a。如果直接返回&mut self.0.0,Rust会默认给这个返回值绑定'b的生命周期,但函数签名要求返回'a;同时Rust还担心后续你可能通过self再次访问这个引用,造成可变引用的别名冲突,所以直接抛出错误。
再看Option::take()的关键作用:它会把Option内部的取值取出,同时将原Option置为None。这一步相当于把&'a mut Node<T>这个可变引用的唯一使用权从Wrapper转移到了node变量——Wrapper里的self.0变成None,彻底失去了对原引用的访问权。
至于为什么node的生命周期能满足'a:因为self.0里的引用本身就是'a生命周期的,take()只是把它从Option容器中取出,并没有改变它的生命周期。而且由于Wrapper已经彻底失去了这个引用,Rust可以确定不会有其他地方再使用它,也就不存在别名风险了,所以允许你返回这个带有'a生命周期的引用。
内容的提问来源于stack exchange,提问作者realwangliqiu
相关产品推荐
相关产品推荐

