简体   繁体   English

关于 Rust HashMap 和字符串借用的困惑

[英]Confusion about Rust HashMap and String borrowing

This program accepts an integer N, followed by N lines containing two strings separated by a space.该程序接受一个整数 N,后跟 N 行,其中包含两个由空格分隔的字符串。 I want to put those lines into a HashMap using the first string as the key and the second string as the value:我想将这些行放入一个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]);
    }
}

The program works as intended:该程序按预期工作:

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

When I try to put those parsed strings into a HashMap and uncomment map.insert(data[0], data[1]);当我尝试将这些解析的字符串放入HashMap并取消注释map.insert(data[0], data[1]); , the compilation fails with this error: ,编译失败并出现以下错误:

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() {
...
}
^

I don't understand why this error would come up, since I think the map.insert() expression doesn't borrow the string input at all.我不明白为什么会出现这个错误,因为我认为map.insert()表达式根本不借用字符串input

split_whitespace() doesn't give you two new String s containing (copies of) the non-whitespace parts of the input. split_whitespace()不会为您提供两个包含输入的非空白部分(的副本)的新String Instead you get two references into the memory managed by input , of type &str .相反,您会在由input管理的内存中获得两个引用,类型为&str So when you then try to clear input and read the next line of input into it, you try overwriting memory that's still being used by the hash map.因此,当您尝试清除input并将下一行input读入其中时,您会尝试覆盖哈希映射仍在使用的内存。

Why does split_whitespace (and many other string methods, I should add) complicate matters by returning &str ?为什么split_whitespace (以及许多其他字符串方法,我应该添加)通过返回&str使问题复杂化? Because it's often enough, and in those cases it avoid unnecessary copies.因为这通常就足够了,在这些情况下,它避免了不必要的副本。 In this specific case however, it's probably best to explicitly copy the relevant parts of the string:但是,在这种特定情况下,最好显式复制字符串的相关部分:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM