代码之家  ›  专栏  ›  技术社区  ›  stevensonmt

锈迹斑斑_端_匹配类型不匹配

  •  0
  • stevensonmt  · 技术社区  · 5 年前

    我有下面的代码来计算忽略标点符号的单词数。

    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");

    0 回复  |  直到 5 年前
        1
  •  3
  •   Peter Hall    5 年前

    正如错误所说, trim_end_matches 期望参数是采用 char 但是 char::is_ascii_punctuation 引用它的论点。

    只需添加一个闭包即可进行转换:

    .map(|word| word.trim_end_matches(|c| char::is_ascii_punctuation(&c)))
    

    大多数谓词方法 烧焦 (例如:。 is_alphanumerc )接受 self 但是,出于历史原因(参见 RFC comments ),特定于ASCII的方法 &self .对于非ASCII方法,您可以执行以下操作,例如:

    .map(|word| word.trim_end_matches(char::is_alphanumeric))