为什么不能将用于记忆函数的静态散列图借用为可变的?
Why cant a static hashmap for a memoizing function be borrowed as mutable?
我正在尝试在 Rust
中创建一个记忆功能。获取缓存 HashMap
的可变引用时会出现问题。我对类型系统仍然没有信心,我有点挣扎。
use std::collections::HashMap;
use std::hash::Hash;
fn memoize<A, B, F>(f: F, cache: &'static HashMap<A, B>) -> impl Fn(A) -> B
where
A: Eq + Hash + Copy,
B: Clone,
F: Fn(A) -> B,
{
move |value: A| {
if !cache.contains_key(&value) {
cache.insert(value, f(value.clone()));
}
let res = cache.get(&value).unwrap();
res.clone()
}
}
错误是:
error[E0596]: cannot borrow immutable borrowed content `**cache` as mutable
--> src/lib.rs:12:13
|
12 | cache.insert(value, f(value.clone()));
| ^^^^^ cannot borrow as mutable
为什么静态生命周期参数不能可变?
在 Rust 中,默认情况下变量是不可变的,因此您不能改变未声明为 mut
的变量。 'static
lifetime 不会影响可变性,只会影响变量的寿命。
A Fn
[...] 可以重复调用而不改变状态。。而这正是问题所在。您想改变环境(在本例中是您的 HashMap
)。
您必须使用 FnMut
才能改变环境。
如果你使用Entry API,你可以简化你的代码:
use std::collections::HashMap;
use std::hash::Hash;
fn memoize<A, B, F>(f: F, cache: &'static mut HashMap<A, B>) -> impl FnMut(A) -> B
where
A: Eq + Hash + Copy,
B: Clone,
F: Fn(A) -> B,
{
move |value: A| {
let res = cache.entry(value).or_insert_with(|| f(value));
res.clone()
}
}
作为旁注,如果您使用 #[feature(nll)]
编译代码,错误消息实际上非常好。
error[E0596]: cannot borrow `*cache` as mutable, as `Fn` closures cannot mutate their captured variables
--> src/lib.rs:14:13
|
14 | cache.insert(value, f(value.clone()));
| ^^^^^ cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`
我正在尝试在 Rust
中创建一个记忆功能。获取缓存 HashMap
的可变引用时会出现问题。我对类型系统仍然没有信心,我有点挣扎。
use std::collections::HashMap;
use std::hash::Hash;
fn memoize<A, B, F>(f: F, cache: &'static HashMap<A, B>) -> impl Fn(A) -> B
where
A: Eq + Hash + Copy,
B: Clone,
F: Fn(A) -> B,
{
move |value: A| {
if !cache.contains_key(&value) {
cache.insert(value, f(value.clone()));
}
let res = cache.get(&value).unwrap();
res.clone()
}
}
错误是:
error[E0596]: cannot borrow immutable borrowed content `**cache` as mutable
--> src/lib.rs:12:13
|
12 | cache.insert(value, f(value.clone()));
| ^^^^^ cannot borrow as mutable
为什么静态生命周期参数不能可变?
在 Rust 中,默认情况下变量是不可变的,因此您不能改变未声明为 mut
的变量。 'static
lifetime 不会影响可变性,只会影响变量的寿命。
A Fn
[...] 可以重复调用而不改变状态。。而这正是问题所在。您想改变环境(在本例中是您的 HashMap
)。
您必须使用 FnMut
才能改变环境。
如果你使用Entry API,你可以简化你的代码:
use std::collections::HashMap;
use std::hash::Hash;
fn memoize<A, B, F>(f: F, cache: &'static mut HashMap<A, B>) -> impl FnMut(A) -> B
where
A: Eq + Hash + Copy,
B: Clone,
F: Fn(A) -> B,
{
move |value: A| {
let res = cache.entry(value).or_insert_with(|| f(value));
res.clone()
}
}
作为旁注,如果您使用 #[feature(nll)]
编译代码,错误消息实际上非常好。
error[E0596]: cannot borrow `*cache` as mutable, as `Fn` closures cannot mutate their captured variables
--> src/lib.rs:14:13
|
14 | cache.insert(value, f(value.clone()));
| ^^^^^ cannot borrow as mutable
|
help: consider changing this to accept closures that implement `FnMut`