rust - 如何返回对存储在结构成员中的可选盒装特征的可变引用
问题描述
我的目标是返回对存储在 Box 中的 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
我真的看不出寿命会在哪里延长。
尝试替换 &mut **x
为as_mut
也无济于事。
解决方案
发生这种情况是因为编译器中的一个怪癖。让我们扩展 中的生命周期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)>
。应用于 trait 对象的生命周期约束的这种细微差别不能通过简单的强制来解决,因为可变引用对于 trait 对象的生命周期是不变的。
我们可以做的是要么同意输出一个可变引用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())
}
或者告诉编译器Option<&'a mut (dyn Baz + 'a)>
通过其他方式解析表达式,例如使用手动match
语句、?
运算符或强制转换。
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 类型的协方差
推荐阅读
- symfony - 在购物车中获取比例单位
- excel - Excel 循环、计算和着色宏跳过单元格
- c++ - GStreamer + OpenCV 视频处理问题
- python - 为什么这不是专门在 chrome webdriver-browser (selenium-python) 中打开新标签?
- discord - 如何将某人作为开发人员添加到不和谐机器人
- html - 由于路径错误,HTML 不加载 CSS
- go - Windows中的Golang cmd命令
- laravel-5 - 方法 App\\Http\\Controllers\\Controller::show 不存在
- mysql - 将参数传递给 MySQL 查询 - VB6
- python - Bokeh 中带有下拉菜单的折线图不起作用