提问人:acctech007 提问时间:5/31/2023 更新时间:5/31/2023 访问量:54
Rust HashMap 插入方法使用生成的字符串生成借用检查器错误
Rust HashMap insert method producing borrow-checker error with generated string
问:
我正在尝试 Rust,但很难理解为什么编译器在终生问题上使我的代码失败。这是问题所在。
以下是使用货物工作区组织代码的方式。
.
├── Cargo.lock
├── Cargo.toml
├── README.md
├── collections
│ ├── Cargo.toml
│ └── src
└── utils
├── Cargo.toml
└── src
我在 lib 中定义了一个函数,我从集合中调用它。generate_string
utils
/// defined in utils/src/lib.rs
pub fn generate_string (size: usize) -> String {
Alphanumeric.sample_string(&mut rand::thread_rng(), size)
}
现在尝试从 collections/src/stone.rs 调用它
mod tets {
fn test_normalize_large_input() {
let map_lenght = 50000;
let err_message = "normalize handles large inputs.";
let mut profile: HashMap<&str, f64> = HashMap::new();
for _ in 0..map_lenght {
let key: String = utils::generate_string(8);
profile.insert(&key, 1.0); // this won't work
}
let got = normalize(&profile).unwrap();
assert_eq!(got.len(), 1, "{}", err_message);
assert!(got.contains_key("singleton"), "{}", err_message);
}
}
我有一个编译问题。
|
462 | let key: String = utils::generate_string(8);
| --- binding `key` declared here
463 | profile.insert(&key, 1.0);
| ^^^^ borrowed value does not live long enough
464 | }
| - `key` dropped here while still borrowed
这是我不明白的。我看不出哪个变量或函数借用了变量。因为当我检查文档时,该方法没有借用密钥参数。key
insert
HashMap
问题是,1)什么是实际借款?如何在地图中插入返回 没有问题?key
utils::generate_string
我试图以这种方式克隆变量。我期望克隆会复制内存内容,以便密钥的生存期不再是问题。但它也不起作用。这次我又收到一个错误。key
profile.insert(key.clone().as_str(), 1.0);
|
463 | profile.insert(key.clone().as_str(), 1.0);
| ---------------^^^^^^^^^^^---------------- temporary value is freed at the end of this statement
| | |
| | creates a temporary value which is freed while still in use
| borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
实际上,我不想克隆变量。我确实尝试过这个,看看它会如何表现。
提前感谢您的帮助。
答:
我看不出哪个变量或函数借用了变量键。因为 HashMap 的 insert 方法在我查看文档时没有借用键参数。
insert
没有,但当你写的时候你会这样做
profile.insert(&key, 1.0);
那是借来的。您不是在地图中插入,而是在插入对 的引用。key
key
因为 是循环作用域所拥有的,所以它在迭代结束时停止,因此引用是悬空的,这是非法的。key
String
您需要将地图设为 a,以便您可以在地图中移动,并且地图从那里开始拥有字符串。HashMap<String, f64>
key
profile.insert(key.clone().as_str(), 1.0);
这只是同一问题的更复杂版本(实际上是一个更糟糕的问题)。 是一个临时的,它被放在语句的末尾(紧接在完成和返回之后),并且你插入了对该临时的引用,这是一个更短的借用。key.clone()
insert
你真的应该仔细考虑阅读或重读 Rust 这本书,因为你在这里遇到了语言的绝对基础,这不会是一次有趣的体验。Rust 不是一种简单的语言,除非你有 C 或 C++ 的大师级知识,否则几乎不可能通过在编辑器中学习,有些概念是新颖的,没有非学术语言,并且尽管编译器试图提供帮助,但它会让你很难阻止,它不能为问题提供完整的指导。也许有一天,但不是现在,也不是很快。
评论
profile.insert(&key, 1.0);
借用 as an .但是,它将在循环体的末尾被丢弃(解除分配,销毁)。这就是您收到错误的原因。改为 a。key
&str
key
String
profile
HashMap<String, f64>
normalize
key