繁体   English   中英

如何返回对存储在struct成员中的Optional boxed Trait的可变引用

[英]How do I return a mutable reference to an Optional boxed Trait stored in a struct member

我的目标是返回对存储在Box中的特征对象的可变引用。

这似乎与有关借用对可选struct成员的引用的问题有关 ,但是主要区别似乎在于trait对象的存在。 我也试图返回一个选项而不是结果。

尝试使用相同的方法似乎会导致终身问题。

样例代码:

trait Baz {}

#[derive(Debug)]
struct Foo;

impl Baz for Foo {}

struct Bar {
    data: Option<Box<Baz>>,
}

enum BarErr {
    Nope,
}

impl Bar {
    fn borrow_mut(&mut self) -> Option<&mut Baz> {
        self.data.as_mut().map(|x| &mut **x)
    }
}

游乐场链接。

错误信息:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/lib.rs:20:9
   |
20 |         self.data.as_mut().map(|x| &mut **x)
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
   |
   = note: expected type `std::option::Option<&mut dyn Baz>`
              found type `std::option::Option<&mut (dyn Baz + 'static)>`
note: the anonymous lifetime #1 defined on the method body at 19:5...
  --> src/lib.rs:19:5
   |
19 | /     fn borrow_mut(&mut self) -> Option<&mut Baz> {
20 | |         self.data.as_mut().map(|x| &mut **x)
21 | |     }
   | |_____^
   = note: ...does not necessarily outlive the static lifetime

我真的看不到寿命会在哪里延长。

另外尝试用as_mut替换&mut **x也无济于事。

发生这种情况是由于编译器中有一个怪癖。 让我们扩展borrow_mut的生存期:

fn borrow_mut<'a>(&'a mut self) -> Option<&'a mut dyn Baz> {

表达方式

self.data.as_mut().map(|x| &mut **x)

推断类型为Option<&mut dyn (Baz + 'static)> ,而函数期望输出Option<&'a mut dyn (Baz + 'a)> 应用于特征对象的生命周期约束的这种细微差别无法通过强制转换解决,因为可变引用相对于特征对象的生命周期是不变的。

我们可以做的就是同意输出对dyn Baz + 'static的可变引用:

fn borrow_mut<'a>(&'a mut self) -> Option<&'a mut (dyn Baz + 'static)> {
   self.data.as_mut().map(|x| x.as_mut())
}

或者告诉编译器通过其他方式(例如,使用手动match语句? Option<&'a mut (dyn Baz + 'a)>将表达式解析为Option<&'a mut (dyn Baz + 'a)> ? 运算符或演员表。

impl Bar {
    fn borrow_mut(&mut self) -> Option<&mut dyn Baz> {
        self.data.as_mut().map(|x| &mut **x as &mut dyn Baz)
    }
}

另请参阅: Rust中Box类型的协方差

似乎使用解构语法似乎可以解决此问题:以下代码可以正常编译:

fn borrow_mut(&mut self) -> Option<&mut Baz> {
    match &mut self.data {
        Some(e) => Some(e.as_mut()),
        None => None,
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM