Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 从向量中获取特征对象引用_Rust - Fatal编程技术网

Rust 从向量中获取特征对象引用

Rust 从向量中获取特征对象引用,rust,Rust,我正在努力从Vec中获取一个元素,它是一个具有生命周期的引用。我已将代码简化为: pub trait Runnable {} pub struct RunList<'a> { runnables: Vec<&'a mut Runnable>, } impl<'a> RunList<'a> { pub fn get(&self, id: usize) -> &'a mut Runnable {

我正在努力从
Vec
中获取一个元素,它是一个具有生命周期的引用。我已将代码简化为:

pub trait Runnable {}

pub struct RunList<'a> {
    runnables: Vec<&'a mut Runnable>,
}

impl<'a> RunList<'a> {
    pub fn get(&self, id: usize) -> &'a mut Runnable {
        self.runnables[id]
    }
}

fn main() {}
pub trait Runnable{}
发布结构运行列表,
}
恳求{
pub fn get(&self,id:usize)->&'a mut Runnable{
self.runnables[id]
}
}
fn main(){}

这将产生以下错误:

error[E0495]:由于需求冲突,无法为函数调用中的生存期参数推断适当的生存期
-->src/main.rs:9:9
|
9 | self.runnables[id]
|         ^^^^^^^^^^^^^^^^^^
|
注意:首先,生命周期不能超过8:5在方法体上定义的匿名生命周期#1。。。
-->src/main.rs:8:5
|
8 |/pub fn get(&self,id:usize)->&a mut Runnable{
9 | | self.runnables[id]
10| |     }
| |_____^
注意:…这样引用就不会超过借用的内容
-->src/main.rs:9:9
|
9 | self.runnables[id]
|         ^^^^^^^^^^^^^^
注意:但是,生存期必须对impl上定义的7:1的生存期“a”有效。。。
-->src/main.rs:7:1
|
7 | impl{
| ^^^^^^^^^^^^^^^^^^^^
=注意:…因此表达式是可赋值的:
应为&'a mut Runnable+'a
已找到多个可运行的+'a(&M)

首先,从
get
的返回值类型中删除生存期参数
'a

pub trait Runnable {}

pub struct RunList<'a> {
    runnables: Vec<&'a mut Runnable>,
}

impl<'a> RunList<'a> {
    pub fn get(&mut self, id: usize) -> &mut Runnable {
        self.runnables[id]
    }
}

fn main() {}
self.runnables[id]
不可变地借用
&一个mut Runnable
并隐式地取消引用它。您不能将
&一个mut Runnable
移出这个不可变的借用。相反,您可以可变地重新借用需要
self
可变借用的Runnable:

impl<'a> RunList<'a> {
    pub fn get(&mut self, id: usize) -> &mut Runnable {
        &mut *self.runnables[id]
    }
}
相当于:

pub fn get(&mut self, id: usize) -> &mut Runnable {
    let r: &&mut (Runnable + 'a)  = self.runnables.index(id);
    *r
}
索引
返回对
&'a mut Runnable
的不可变引用,其类型为
&&mut(Runnable+'a)
。返回
*r
不起作用,因为您无法将不可变引用1移出借用的内容,并且不可变引用中的数据也不能以不可变方式借用(
&mut**r
不起作用)。因此,您需要
index
的版本,该版本授予对索引元素的可变访问权:
index\u mut

pub fn get(&mut self, id: usize) -> &mut Runnable {
    let r: &mut &'a mut (Runnable + 'a)  = self.runnables.index_mut(id);
    *r
}
这是可行的,因为
*r
实际上是可变地在内部重新加载
可运行的
&mut**r
).与上述不可变引用
r
的情况相反,可变地借用可变引用
r
中的数据是完全正确的。当执行
&mut**r
时,参数
'a
在解引用过程中丢失。因此,返回
&a mut Runnable
,而不是
&mut Runnable
在这里不起作用

最后,
&mut*self.runnables[id]
告诉编译器隐式解析为
*self.runnables.index\u mut(id)
,而不是
*self.runnables.index(id)
*&mut-self.runnables[id]



1可变引用不是
Copy
。如果您将代码中的所有
&'a mut Runnable
更改为
&'a Runnable
,它将编译,因为不可变引用是
Copy

好的,谢谢!我不完全理解,但它解决了我的问题(或者将它移到了其他地方…:-),所以再次感谢你。@AndrewMackenzie我补充了一个更详细的解释。它应该让事情变得清楚。
pub fn get(&mut self, id: usize) -> &mut Runnable {
    let r: &mut &'a mut (Runnable + 'a)  = self.runnables.index_mut(id);
    *r
}