关于 Rust HashMap 和 String 借用的困惑
Confusion about Rust HashMap and String borrowing
此程序接受一个整数 N,后跟 N 行,其中包含两个字符串,由 space 分隔。我想将这些行放入 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
s 包含(副本)输入的非空白部分。相反,您获得了两个对 input
类型 &str
管理的内存的引用。因此,当您随后尝试清除 input
并将下一行输入读入其中时,您会尝试覆盖哈希映射仍在使用的内存。
为什么 split_whitespace
(以及许多其他字符串方法,我应该补充)通过返回 &str
使事情复杂化?因为它通常就足够了,在那些情况下它避免了不必要的副本。但是,在这种特定情况下,最好明确复制字符串的相关部分:
map.insert(data[0].clone(), data[1].clone());
此程序接受一个整数 N,后跟 N 行,其中包含两个字符串,由 space 分隔。我想将这些行放入 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
s 包含(副本)输入的非空白部分。相反,您获得了两个对 input
类型 &str
管理的内存的引用。因此,当您随后尝试清除 input
并将下一行输入读入其中时,您会尝试覆盖哈希映射仍在使用的内存。
为什么 split_whitespace
(以及许多其他字符串方法,我应该补充)通过返回 &str
使事情复杂化?因为它通常就足够了,在那些情况下它避免了不必要的副本。但是,在这种特定情况下,最好明确复制字符串的相关部分:
map.insert(data[0].clone(), data[1].clone());