【发布时间】:2019-10-13 03:21:00
【问题描述】:
我试图了解两者之间的区别
let rows = Vec::new();
for (k, v) in my_btree { // BTreeMap<i64, String>
rows.push((&k, &v)) // k and v don't live long enough.
}
和:
let rows = Vec::new();
for (k, v) in &my_btree { // BTreeMap<i64, String>
rows.push((k, v))
}
有人能解释一下迭代&my_btree和迭代my_btree之间的区别吗?
具体来说,我想了解所有权如何变化以及上述两个示例中引用了哪些内存
这是我正在尝试做的一个完整示例(target_function 是我正在使用的一个库,它具有与此处类似的函数签名,因此无法更改):
use std::collections::BTreeMap;
struct SomeStruct {
x: BTreeMap<i64, String>
}
fn target_function(rows: &[(&i64, &String)]) {
for row in rows.iter() {
println!("{:#?}", row);
}
}
fn test(ss: SomeStruct) {
let mut rows = Vec::new();
for (k, v) in &ss.x {
rows.push((k, v));
}
target_function(&rows[..]);
}
fn main() {
let mut a = BTreeMap::new();
a.insert(1, "hello".to_string());
a.insert(2, "goodbye".to_string());
let mystruct = SomeStruct{x: a};
test(mystruct);
}
【问题讨论】:
-
实际区别在于
(&k, &v)和(k, v)。两个 sn-ps 都可以与rows.push((k, v))一起使用,但都不能与(&k, &v)一起使用。 -
简短回答:当迭代
&my_btree时,值是借用的,因此您会获得与集合相关的生命周期的引用。但是当迭代my_btree时,你会得到拥有的值。如果您创建它们的引用,它们只会在k和v超出范围之前有效。 -
@Zefick:感谢您的回答,但我最后不得不引用(请参阅底部的代码块),这就是为什么我有 (&k, &v) 并且主要是来说明为什么它们彼此不同。