我需要创建一个引用向量,但看起来这在Rust中难以置信。这是我当前实现的简化版本:
struct Object {
// stuff
}
fn f(o: Object) -> Object {
// do stuff
o
}
fn main() {
let vector = vec![Object {}, Object {}];
let mut objects: Vec<Object> = vec![];
let mut object_refs: Vec<&Object> = vec![]; // <-- this is what I need
for object in vector {
objects.push(f(object));
}
for i in 0..objects.len() {
object_refs.push(&objects[i]);
}
}
有更好的方法吗?
以下是生锈操场的链接:https://play.rust-lang.org/?gist=2755aa64d96e0632e47488ab10908979&version=stable&backtrace=0
感谢您指点我的问题。我实际上已经查过那篇文章,发现它并没有完全解决我的问题。
以下是我如何调整该问题的最佳答案中提出的每个“版本”:
let v2: Vec<&Object> = v.iter().map(|s| &f(s)).collect();
let v3: Vec<&Object> = v.iter().map(|s| f(s)).map(std::ops::Deref::deref).collect();
let v4: Vec<&Object> = v.iter().map(|s| f(s) as &Object).collect();
let v5: Vec<&Object> = v.iter().map(|s| &f(s)[..]).collect();
let v6: Vec<&Object> = v.iter().map(|s| { let s: &Object = &f(s); s }).collect();
let v7: Vec<&Object> = v.iter().map(|s| f(s).as_ref()).collect();
let v8: Vec<&str> = v.iter().map(|s| f(s)).map(AsRef::as_ref).collect();
其中一些版本显然仅适用于&String
类型,但为了完整起见,我将其包含在内。你可以在这个生锈的游乐场中运行它们,并验证它们都会抛出错误:
https://play.rust-lang.org/?gist=cc3c8fb1f774f230ad07cdd708aed044&version=stable&backtrace=0
值得一提的是,Object
结构实际上是从外部包装箱导入的类型,因此我无法以任何方式对其进行修改。
基本问题是f(s)
的范围在迭代器中。如果您使用闭包|s| &f(s)
,则f(s)
过早释放:
error: borrowed value does not live long enough
--> <anon>:22:49
|
22 | let v2: Vec<&Object> = v.iter().map(|s| &f(s)).collect();
| ---^
| | |
| | temporary value dropped here while still borrowed
| temporary value created here
...
29 | }
| - temporary value needs to live until here
我最初的尝试涉及将顶层的实际f(s)
值存储在一个数组中,然后创建第二个数组,并引用第一个数组。它有效,但它非常冗长和笨拙。如果你能指出一个更好的方法,我将不胜感激。