rust - 如何确保 self 在不借入的情况下超过返回值
问题描述
假设有这样的事情:
trait B {}
struct BB {}
impl B for BB {}
struct A {}
impl A {
// With this, A can be dropped before B
// fn get_b(&mut self) -> Box<dyn B> {...}
fn get_b<'a>(&'a mut self) -> Box<dyn B + 'a> {...}
fn mut_a(&mut self) {}
}
fn main() {
let mut a = A {};
let b = a.get_b();
// These lines don't compile
a.mut_a(); // A is borrowed. Is there any way to make this compile?
// Does not compile and should not. b must be dropped before a
drop(a);
drop(b);
}
有什么方法可以确保在不a
借用的情况下b
(出于unsafe
代码原因)寿命长a
吗?
编辑:a
和都b
必须是可变的(如果声明mut
)并且应该保持可移动。它唯一需要确保的是 B 在 A 之前被删除。
解决方案
如果您提供A
两个字段,例如lifetime
and data
,您可以对get_b
进行共享引用lifetime
并对mut_a
进行可变引用data
:
trait B {}
struct BB {}
impl B for BB {}
struct A {
pub lifetime: ALifetime,
pub data: AData,
#[allow(dead_code)]
private: (), // prevent destructuring
}
struct ALifetime {}
struct AData {}
impl A {
fn new() -> Self {
Self { lifetime: ALifetime {}, data: AData {}, private: () }
}
}
impl ALifetime {
fn get_b<'a>(&'a self) -> Box<dyn B + 'a> { Box::new(BB{}) }
}
impl AData {
fn mut_a(&mut self) {}
}
fn main() {
let mut a = A::new();
let b = a.lifetime.get_b();
a.data.mut_a(); // Only `a.data` is borrowed here.
// drop(b);
drop(a); // Not allowed. b must be dropped before a
}