hashmap - 关于 Rust HashMap 和 String 借用的困惑

标签 hashmap rust borrowing

该程序接受一个整数 N,后跟 N 行,其中包含两个由空格分隔的字符串。我想将这些行放入 HashMap 中,使用第一个字符串作为键,第二个字符串作为值:

use std::collections::HashMap;
use std::io;

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input)
        .expect("unable to read line");
    let desc_num: u32 = match input.trim().parse() {
        Ok(num) => num,
        Err(_) => panic!("unable to parse")
    };

    let mut map = HashMap::<&str, &str>::new();
    for _ in 0..desc_num {
        input.clear();
        io::stdin().read_line(&mut input)
            .expect("unable to read line");
        let data = input.split_whitespace().collect::<Vec<&str>>();
        println!("{:?}", data);
        // map.insert(data[0], data[1]);
    }
}

程序按预期工作:

3
a 1
["a", "1"]
b 2
["b", "2"]
c 3
["c", "3"]

当我尝试将这些已解析的字符串放入 HashMap 并取消注释 map.insert(data[0], data[1]); 时,编译失败并显示这个错误:

error: cannot borrow `input` as mutable because it is also borrowed as immutable [E0502]
        input.clear();
        ^~~~~
note: previous borrow of `input` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `input` until the borrow ends
        let data = input.split_whitespace().collect::<Vec<&str>>();
                   ^~~~~
note: previous borrow ends here
fn main() {
...
}
^

我不明白为什么会出现这个错误,因为我认为 map.insert() 表达式根本没有借用字符串 input

最佳答案

split_whitespace() 不会为您提供两个包含输入的非空白部分(副本)的新 String。相反,您会得到两个对 &str 类型的 input 管理的内存的引用。因此,当您随后尝试清除 input 并将下一行输入读入其中时,您会尝试覆盖 HashMap 仍在使用的内存。

为什么 split_whitespace(以及我应该补充的许多其他字符串方法)通过返回 &str 使事情复杂化?因为它通常就足够了,在那些情况下它避免了不必要的副本。然而,在这种特定情况下,最好明确复制字符串的相关部分:

map.insert(data[0].clone(), data[1].clone());

关于hashmap - 关于 Rust HashMap 和 String 借用的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38008547/

相关文章:

Java 哈希表和 HashMap

java - jsp中从hashmap中获取key和value

file - Rust 读取文件

rust - 不能在 Rc 中借用为可变的

java - 如何修复 java.util.ConcurrentModificationException

java - 以 "MMMyyyy"为键对 map 进行排序

rust - 如何将生命周期设置为闭包中捕获的值?

struct - Rust 构建器模式是否必须使用冗余结构代码?

function - 我想将一个向量的引用传递给一个函数,然后在那里修改它并作为向量返回

rust - 为什么从 Rust 中的函数返回一个 &[u8] 而不是 u8 借用自己?