rust 使用range()迭代BTreeMap-关于被迭代类型的问题

5us2dqdw  于 2023-03-02  发布在  其他
关注(0)|答案(1)|浏览(146)

我是非常新的生 rust ,不能弄清楚以下行为:
鉴于此:

let mut map = BTreeMap::new();
map.insert(3, vec!["a".to_string()]);
map.insert(5, vec!["b".to_string()]);
map.insert(8, vec!["c".to_string()]);

为什么下面的“&v”具有类型Vec<String>,(第i块)

for (&k, &v) in map.range(4..) {
    println!("{}: {:?}", k, v);
}

而下面的“v”具有类型&Vec<String>(块ii)。

for (&k, v) in map.range(4..) {
    println!("{}: {:?}", k, v);
}

如果“block ii”中的v是&Vev<String>,这是否意味着块i中的v必须是&&Vev<String>(对引用的引用?),因为我在块i中的v添加了&。对我来说,奇怪的是,在v添加&号会使Vec<String>成为一个拥有的值。块i.将不会编译,因为v正在从共享引用中移出。
Playground link(可以在&v和v之间切换)
一个很受欢迎的机器人告诉我:
这段代码无法编译,因为BTreeMap的range方法返回一个迭代器,该迭代器以(key,value)元组的形式产生对其键-值对的引用,但是,在for循环中,模式(&k,&v)试图将这些元组解构为分别对键和值的引用。
问题是range方法产生了对键-值对的引用,而不是键和值本身。要解决这个问题,可以将模式更改为(&k,v),以匹配对键和拥有值的引用:
我不太明白关于将代码分解为引用的观点。

zdwk9cvp

zdwk9cvp1#

如果“block ii”中的v是&Vec<String>,这是否意味着block i中的v必须是&&Vec<String>(对引用的引用?)
不,因为你没有给它添加引用。当你调用

for (&k, &v) in map.range(4..)

称为模式解构。调用map.range(4..)会创建一个迭代器,其中每个元素的类型都是(&u8, &Vec<String>)。您无法对其进行任何更改。但是,您可以使用模式来解构元组,并将其包含的值绑定到变量(在您的示例中为kv)。第一个示例将kv绑定到解引用的值,例如,k具有类型u8v具有类型Vec<String>,这取决于您如何析构模式(使用&k&v中的&)。&v不是对v的引用,这意味着vmap.range返回的引用后面的值。

相关问题