关于Rust HashMap和String借用的困惑 [英] Confusion about Rust HashMap and String borrowing
问题描述
此程序接受整数N,后接N行,其中包含由空格分隔的两个字符串。我想使用第一个字符串作为键,第二个字符串作为值,将这些行放入 HashMap
中:
This program accepts an integer N, followed by N lines containing two strings separated by a space. I want to put those lines into a HashMap
using the first string as the key and the second string as the value:
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]);
,编译失败并显示以下错误:
When I try to put those parsed strings into a HashMap
and uncomment 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() {
...
}
^
我不明白为什么会出现此错误,因为我认为 map.insert( )
表达式根本不借用字符串 input
。
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.
推荐答案
split_whitespace()
不会给您两个新的 String
包含(副本)输入的非空白部分。而是在类型为& str
的 input
管理的内存中获得两个引用。因此,当您随后尝试清除 input
并读取输入的下一行时,尝试覆盖哈希映射仍在使用的内存。
split_whitespace()
doesn't give you two new String
s containing (copies of) the non-whitespace parts of the input. Instead you get two references into the memory managed by input
, of type &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.
为什么 split_whitespace
(以及许多其他字符串方法,我应该添加)通过返回& str <使事情复杂化/ code>?因为通常就足够了,在这种情况下,避免不必要的复制。但是,在这种特定情况下,最好最好显式复制字符串的相关部分:
Why does split_whitespace
(and many other string methods, I should add) complicate matters by returning &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());
这篇关于关于Rust HashMap和String借用的困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!