我有下面的代码来做一个字数统计,其中忽略标点符号。
use std::collections::HashMap;
fn word_count(words: &str) -> HashMap<String, u32> {
let mut hm: HashMap<String, u32> = HashMap::new();
words
.split_whitespace()
.map(|word| word.trim_end_matches(char::is_ascii_punctuation))
.map(|word| {
hm.entry(word.to_string())
.and_modify(|val| *val += 1)
.or_insert(0)
});
hm
}
但编译器抱怨
error[E0631]: type mismatch in function arguments
--> src/lib.rs:7:26
|
7 | .map(|word| word.trim_end_matches(char::is_ascii_punctuation))
| ^^^^^^^^^^^^^^^^
| |
| expected signature of `fn(char) -> _`
| found signature of `for<'r> fn(&'r char) -> _`
|
= note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `for<'r> fn(&'r char) -> bool {std::char::methods::<impl char>::is_ascii_punctuation}`
我无法弄清楚错误的真正含义或我的用法与trim_end_matches
的文档有何不同:assert_eq!("123foo1bar123".trim_end_matches(char::is_numeric), "123foo1bar");
正如错误所说,trim_end_matches
期望该论证是一个接受char
的函数,但是char::is_ascii_punctuation
通过引用得出它的论证。
你可以添加一个闭包来转换:
.map(|word| word.trim_end_matches(|c| char::is_ascii_punctuation(&c)))
关于char
(例如is_alphanumerc
)的大多数谓词方法都采用self
,但出于历史向后兼容性原因(参见RFC comments),ASCII特定方法采用&self
。对于非ASCII方法,您可以这样做,例如:
.map(|word| word.trim_end_matches(char::is_alphanumeric))