使用trim_end_matches作为关闭函数键入不匹配:预期的签名...找到的签名为“ for <'r> ...”

时间:2019-03-18 16:54:23

标签: rust char ascii predicate

我在下面的代码中进行了忽略标点的单词计数。

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_matchesassert_eq!("123foo1bar123".trim_end_matches(char::is_numeric), "123foo1bar");

的文档中的用法有何不同

1 个答案:

答案 0 :(得分:3)

如错误所述,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的方法采用{ {1}}。对于非ASCII方法,您可以这样做,例如:

&self