gpt4 book ai didi

rust - 改变 HashMap> 中的向量元素

转载 作者:行者123 更新时间:2023-12-05 09:32:18 25 4
gpt4 key购买 nike

我已经解决了一个我看到的问题 example :

use std::collections::HashMap;

fn process(mut inputs: Vec<String>) -> Vec<String> {

// keep track of duplicate entries in the input Vec
let mut duplicates: HashMap<String, Vec<&mut String>> = HashMap::new();
for input in &mut inputs {
duplicates.entry(input.clone())
.or_insert_with(|| Vec::new())
.push(input);
}

// modify the input vector in place to append the number of each duplicate
for (key, instances) in duplicates {
for (i, instance) in instances.iter().enumerate() {
*instance = format!("{}_{}", instance, i);
}
}

return inputs;
}

fn main() {
println!("results: {:?}", process(vec![
String::from("test"),
String::from("another_test"),
String::from("test")
]));
}

我希望这会打印类似 results: test_0, another_test_0, test_1 的内容,但我却遇到了构建问题:

error[E0308]: mismatched types
--> src/main.rs:13:25
|
13 | *instance = format!("{}_{}", instance, i);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&mut String`, found struct `String`
|

我对 Rust 还是有点陌生​​,所以还没有真正在网上找到任何有用的东西。我希望我在做一些愚蠢的事情。在此先感谢您的帮助!

最佳答案

for (key, instances) in duplicates {
for (i, instance) in instances.iter().enumerate() {
*instance = format!("{}_{}", instance, i);
}
}

for (key, instances) in duplicates调用 IntoIterator HashMap<String, Vec<&mut String>> 上的特征, 与

type Item = (String, Vec<&mut String>);

所以 instances: Vec<&mut String> .1 instances.iter()然后生成对 instances 元素的引用, 所以 instance: &&mut String .所以instance需要取消引用两次才能访问 inputs 中的元素,不幸的是,它实际上不起作用:

error[E0594]: cannot assign to `**instance` which is behind a `&` reference
--> src/main.rs:14:13
|
13 | for (i, instance) in instances.iter().enumerate() {
| -------- help: consider changing this to be a mutable reference: `&mut &mut String`
14 | **instance = format!("{}_{}", instance, i);
| ^^^^^^^^^^ `instance` is a `&` reference, so the data it refers to cannot be written

问题是我们不允许修改 T背后的值(value)&&mut T .原因如下:不可变引用可以自由复制,所以可能有多个&&mut T指向相同 &mut T 的实例, 打败 &mut 的抗锯齿属性.

因此,我们必须改变instance的类型至 &mut &mut String , 通过使用 mut.iter_mut() :

for (key, mut instances) in duplicates {
for (i, instance) in instances.iter_mut().enumerate() {
**instance = format!("{}_{}", instance, i);
}
}

key不需要,我们可以使用 .values_mut() ,所以 instances本身变成一个&mut :

for instances in duplicates.values_mut() {
for (i, instance) in instances.iter_mut().enumerate() {
**instance = format!("{}_{}", instance, i);
}
}

1 我们将使用 var: type表示var类型为 type .


一般来说,存储在容器中的引用(尤其是可变引用)使用起来很乏味,所以我推荐一种替代方法:(为简单起见,使用就地接口(interface))

use std::{collections::HashMap, fmt::Write};

fn process(texts: &mut Vec<String>) {
let mut counter = HashMap::<String, usize>::new();

for text in texts.iter_mut() {
let count = counter.entry(text.clone()).or_insert(0);
write!(text, "_{}", count).unwrap();
*count += 1;
}
}

( playground )

关于rust - 改变 HashMap<String, Vec<&mut String>> 中的向量元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68157806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com