我对使用 Rust 比较陌生,我将它用于 Advent of Code 来帮助我学习。对于第四个问题,我想创建一个查找表,使用 HashMap 将字符串键映射到函数值。我知道 Rust 没有用于创建 HashMap 文字的语法糖,所以我从一个切片创建我的 HashMap。当我使用 fn 函数指针时,一切正常:
type ValidatorFn = fn(&str) -> bool;
...
let validation_rules: HashMap<&str, ValidatorFn> = [
("byr", validate_birth_year as ValidatorFn), // "as" cast is necessary here...
("iyr", validate_issue_year),
("eyr", validate_expiration_year),
("hgt", validate_height),
("hcl", validate_hair_colour),
("ecl", validate_eye_colour),
("pid", validate_passport_id),
]
.iter()
.cloned()
.collect();
但是,这限制了我只能存储使用fn关键字定义的函数而不是闭包。作为一个练习,我想重写我的代码以使用盒装Fn特征对象而不是fn指针来允许使用闭包或函数。但是,我天真地尝试这样做是行不通的:
type ValidatorFn = Box<dyn Fn(&str) -> bool>;
...
let validation_rules: HashMap<&str, ValidatorFn> = [
("byr", Box::new(validate_birth_year) as ValidatorFn),
("iyr", Box::new(validate_issue_year)),
("eyr", Box::new(validate_expiration_year)),
("hgt", Box::new(validate_height)),
("hcl", Box::new(validate_hair_colour)),
("ecl", Box::new(validate_eye_colour)),
("pid", Box::new(validate_passport_id)),
]
.iter()
.cloned()
.collect();
给出多个编译器错误:
error[E0277]: the trait bound `dyn for<'r> Fn(&'r str) -> bool: Clone` is not satisfied
--> src/main.rs:21:6
|
21 | .cloned()
| ^^^^^^ the trait `Clone` is not implemented for `dyn for<'r> Fn(&'r str) -> bool`
|
= note: required because of the requirements on the impl of `Clone` for `Box<dyn for<'r> Fn(&'r str) -> bool>`
= note: required because it appears within the type `(&str, Box<dyn for<'r> Fn(&'r str) -> bool>)`
error[E0599]: no method named `collect` found for struct `Cloned<std::slice::Iter<'_, (&str, Box<dyn for<'r> Fn(&'r str) -> bool>)>>` in the current
scope
--> src/main.rs:22:6
|
22 | .collect();
| ^^^^^^^ method not found in `Cloned<std::slice::Iter<'_, (&str, Box<dyn for<'r> Fn(&'r str) -> bool>)>>`
|
::: /Users/ryan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:388:1
|
388 | pub struct Cloned<I> {
| -------------------- doesn't satisfy `_: Iterator`
|
= note: the method `collect` exists but the following trait bounds were not satisfied:
`Cloned<std::slice::Iter<'_, (&str, Box<dyn for<'r> Fn(&'r str) -> bool>)>>: Iterator`
which is required by `&mut Cloned<std::slice::Iter<'_, (&str, Box<dyn for<'r> Fn(&'r str) -> bool>)>>: Iterator`
有人可以帮助破译此错误消息并让我知道我正在尝试做的事情是否可能吗?它似乎告诉我不能克隆 Box 或其内容。我认为 Box 基本上只是指向堆上某个位置的指针,所以我不明白为什么不能克隆它?