Rust 转向Vec<;Rc<;RefCell<;T>&燃气轮机&燃气轮机;进入a&;[&;mut T T]
我得到了一个计数为Rust 转向Vec<;Rc<;RefCell<;T>&燃气轮机&燃气轮机;进入a&;[&;mut T T],rust,lifetime,Rust,Lifetime,我得到了一个计数为RefCells的引用向量,并希望将(mut)引用的Vec传递到RefCells的函数中。引用不需要比函数调用的生命周期长 看起来这应该是可能的(只有一个,像&*x.borrow\u mut()这样的东西就可以了)。我试图保留RefMut和&mut的中间向量来控制生命周期,但我还没有找到让它工作的方法: use std::cell::{RefCell,RefMut}; use std::vec::Vec; use std::rc::Rc; trait SomeTrait {}
RefCell
s的引用向量,并希望将(mut
)引用的Vec
传递到RefCell
s的函数中。引用不需要比函数调用的生命周期长
看起来这应该是可能的(只有一个,像&*x.borrow\u mut()
这样的东西就可以了)。我试图保留RefMut
和&mut
的中间向量来控制生命周期,但我还没有找到让它工作的方法:
use std::cell::{RefCell,RefMut};
use std::vec::Vec;
use std::rc::Rc;
trait SomeTrait {}
struct Wrapper<'a> {
pub r: &'a mut SomeTrait,
}
fn foo(_: &[Wrapper]) {}
fn main() {
let mut v1: Vec<Rc<RefCell<SomeTrait>>> = unimplemented!();
let mut v_rm: Vec<RefMut<_>> = v1.iter_mut().map(|r| r.borrow_mut()).collect();
let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|ref mut rm| Wrapper{ r: &mut ***rm }).collect();
foo(&v_wrapper[..]);
}
使用std::cell::{RefCell,RefMut};
使用std::vec::vec;
使用std::rc::rc;
trait SomeTrait{}
struct Wrapper虽然可以编写以Vec
开头的代码,并从中创建Vec
,但我建议您更改foo
的签名。许多算法不需要片提供的随机访问,如果函数可以接受迭代器而不是片,那么除了调用函数变得更简单之外,您不需要创建两个完整的附加Vec
s。我在想这样的签名
fn foo<I, R>(widgets: I)
where I: IntoIterator<Item=R>,
R: DerefMut<Target=SomeTrait>
{
for widget in widgets {
// ...
}
}
fn-foo(小部件:I)
其中I:into迭代器,
R:DerefMut
{
用于小部件中的小部件{
// ...
}
}
然后,您只需要生成一个迭代器,生成RefMut
,这可以通过v1.iter_mut().map(| x | x.borrow_mut())
轻松实现。举个例子。虽然可以编写以Vec
开头的代码,并从中创建Vec
,但我建议您更改foo
的签名。许多算法不需要片提供的随机访问,如果函数可以接受迭代器而不是片,那么除了调用函数变得更简单之外,您不需要创建两个完整的附加Vec
s。我在想这样的签名
fn foo<I, R>(widgets: I)
where I: IntoIterator<Item=R>,
R: DerefMut<Target=SomeTrait>
{
for widget in widgets {
// ...
}
}
fn-foo(小部件:I)
其中I:into迭代器,
R:DerefMut
{
用于小部件中的小部件{
// ...
}
}
然后,您只需要生成一个迭代器,生成RefMut
,这可以通过v1.iter_mut().map(| x | x.borrow_mut())
轻松实现。举个例子。首先,我同意@delnan的观点,如果可以的话,应该切换到基于迭代器的接口
这段代码的大部分都很好,在将foo
和Wrapper
更改为更灵活一点后,我能够调整其余代码并将其编译:
use std::cell::{RefCell,RefMut};
use std::vec::Vec;
use std::rc::Rc;
trait SomeTrait {}
struct Wrapper<'a, 'b> where 'b: 'a {
pub r: &'a mut (SomeTrait + 'b),
}
fn foo<'a, 'b>(_: &'a mut [Wrapper<'a, 'b>]) where 'b: 'a {}
fn main() {
let mut v1: Vec<Rc<RefCell<SomeTrait>>> = unimplemented!();
let mut v_rm: Vec<RefMut<_>> = v1.iter_mut().map(|r| r.borrow_mut()).collect();
let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|mut rm| Wrapper{ r: &mut **rm }).collect();
foo(&mut v_wrapper[..]);
}
使用std::cell::{RefCell,RefMut};
使用std::vec::vec;
使用std::rc::rc;
trait SomeTrait{}
结构包装器,其中“b:”a{
酒吧r:&'a mut(SomeTrait+'b),
}
fn foo(&'a mut[Wrapper]),其中'b:'a{}
fn main(){
让mut v1:Vec=未实现!();
让mut v_rm:Vec=v1.iter_mut().map(| r | r.borrow_mut()).collect();
让mut v_wrapper:Vec=v_rm.iter_mut().map(| mut rm | wrapper{r:&mut**rm}).collect();
foo(&mut v_包装[…]);
}
这里要理解的关键是,每个trait对象类型都有一个隐式生存期,因为impl可能包含引用。没有SomeTrait
,只有SomeTrait+'a
或SomeTrait+'b
或SomeTrait+'static
代码中的问题是两件事之间的不匹配
- 在您编写的
Rc
中,Rust假设您的意思是Rc(&'a[Wrapper首先,我同意@delnan的观点,如果可以,您应该切换到基于迭代器的接口
这段代码的大部分都很好,在将foo
和Wrapper
更改为更灵活一点后,我能够调整其余代码并将其编译:
use std::cell::{RefCell,RefMut};
use std::vec::Vec;
use std::rc::Rc;
trait SomeTrait {}
struct Wrapper<'a, 'b> where 'b: 'a {
pub r: &'a mut (SomeTrait + 'b),
}
fn foo<'a, 'b>(_: &'a mut [Wrapper<'a, 'b>]) where 'b: 'a {}
fn main() {
let mut v1: Vec<Rc<RefCell<SomeTrait>>> = unimplemented!();
let mut v_rm: Vec<RefMut<_>> = v1.iter_mut().map(|r| r.borrow_mut()).collect();
let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|mut rm| Wrapper{ r: &mut **rm }).collect();
foo(&mut v_wrapper[..]);
}
使用std::cell::{RefCell,RefMut};
使用std::vec::vec;
使用std::rc::rc;
trait SomeTrait{}
结构包装器,其中“b:”a{
酒吧r:&'a mut(SomeTrait+'b),
}
fn foo(&'a mut[Wrapper]),其中'b:'a{}
fn main(){
让mut v1:Vec=未实现!();
让mut v_rm:Vec=v1.iter_mut().map(| r | r.borrow_mut()).collect();
让mut v_wrapper:Vec=v_rm.iter_mut().map(| mut rm | wrapper{r:&mut**rm}).collect();
foo(&mut v_包装[…]);
}
这里要理解的关键是,每个trait对象类型都有一个隐式生存期,因为impl可能包含引用。没有SomeTrait
,只有SomeTrait+'a
或SomeTrait+'b
或SomeTrait+'static
代码中的问题是两件事之间的不匹配
- 在您编写的
Rc
中,Rust假定您的意思是Rc(u:&'a[Wrapper您的Wrange_mut_refs
示例是否从Vec
开始实际起作用?它与我所拥有的非常接近,并且似乎仍然无法解决我的代码存在的生命周期问题。更通用的版本看起来确实是一种改进,只是在这种情况下foo
需要多次迭代,因此依赖IntoIterator
可能不起作用。但是,也许使用DerefMut
可以传入RefMut
@ChrisEmersonwrangle\u mut\u refs
从Vec
工作,但在这个问题上,您已经成功地从Vec
创建了一个片段。我不确定我的Vec
是否正确但必须可用:-(我试图利用你的ref-mut\u-refs
,但没有成功:一生中的错误现在回到v1
活得不够长。@ChrisEmerson有问题的部分是ref-mut
模式——毫不奇怪,我可能会补充,因为这是问题中的代码和wrangle之间的主要区别_mut_-refs
-)编译:您的wrangle_-mut_-refs
示例是否真的从Vec
开始工作?它接近于我所拥有的,但仍然没有看到