在“get_trait_mut”中返回对trait的可变引用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在“get_trait_mut”中返回对trait的可变引用相关的知识,希望对你有一定的参考价值。
考虑以下:
pub trait Inner {}
pub struct Thing<'a> {
inner: &'a Inner,
}
impl<'a> Thing<'a> {
pub fn get_inner(&self) -> &Inner {
self.inner
}
pub fn get_inner_mut(&mut self) -> &mut Inner {
&mut self.inner
}
}
导致:
error[E0277]: the trait bound `&'a (dyn Inner + 'a): Inner` is not satisfied
--> src/lib.rs:13:9
|
13 | &mut self.inner
| -^^^^^^^^^^^^^^
| |
| the trait `Inner` is not implemented for `&'a (dyn Inner + 'a)`
| help: consider removing 1 leading `&`-references
|
= note: required for the cast to the object type `dyn Inner`
这是公平的,所以让我们按照建议,好吗?
与此更改相同:
pub fn get_inner_mut(&mut self) -> &mut Inner {
mut self.inner
}
error: expected expression, found keyword `mut`
--> src/lib.rs:13:9
|
13 | mut self.inner
| ^^^ expected expression
(找到关键字mut是我的本地编译器所说的,而不是下面操场链接中的那个!)
嗯,有道理,对吗?单凭mut
不是表达
但是如何返回一个可变参考呢?
好的,我们试试一下,好吗?
pub fn get_inner_mut(&mut self) -> &mut &Inner {
&mut &self.inner
}
(注意,改变了签名!)
导致:
error[E0308]: mismatched types
--> src/lib.rs:13:9
|
13 | &mut &self.inner
| ^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected type `&mut &dyn Inner`
found type `&mut &'a (dyn Inner + 'a)`
note: the anonymous lifetime #1 defined on the method body at 12:5...
--> src/lib.rs:12:5
|
12 | / pub fn get_inner_mut(&mut self) -> &mut &Inner {
13 | | &mut &self.inner
14 | | }
| |_____^
note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 7:6
--> src/lib.rs:7:6
|
7 | impl<'a> Thing<'a> {
| ^^
这一切都可以通过指定生命周期来解决吗?
答案
我看到的主要问题是Thing
只有inner
的不可变引用。
以下是我对此的看法:
pub trait Inner {}
pub struct Thing<'a> {
inner: &'a mut Inner,
}
impl<'a> Thing<'a> {
pub fn get_inner(&self) -> &Inner {
self.inner
}
pub fn get_inner_mut(&mut self) -> &mut Inner {
&mut *self.inner
}
}
struct SomeInner {}
impl Inner for SomeInner {}
fn main() {
let mut inner = SomeInner {};
let mut thing = Thing { inner: &mut inner };
let inner: &Inner = thing.get_inner();
let mutable_inner: &mut Inner = thing.get_inner_mut();
}
它编译(你可以验证on the playground)
注意:
let mut inner = SomeInner {}
- >inner
是可变的let mut thing
- >thing
也是可变的&mut *self.shape
- >我正在取消引用该引用,然后再次创建一个可变引用
我相信有更复杂的解决方案,我希望其他人能做出贡献。
编辑:正如Shepmaster亲切地指出的那样,根本不需要写&mut *self.shape
。由于我们已经可以访问一个可变引用,只需返回self.inner
就足够了 - 编译器将确保可变性得到尊重。
最后,我的尝试将成为:
impl<'a> Thing<'a> {
pub fn get_inner(&self) -> &Inner {
self.inner
}
pub fn get_inner_mut(&mut self) -> &mut Inner {
self.inner
}
}
以上是关于在“get_trait_mut”中返回对trait的可变引用的主要内容,如果未能解决你的问题,请参考以下文章