【问题标题】:Type mismatch using trim_end_matches as closure function: expected signature ... found signature of "for<'r> ..."使用 trim_end_matches 作为闭包函数的类型不匹配:预期签名...找到“for<'r> ...”的签名
【发布时间】:2019-03-18 16:54:23
【问题描述】:

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

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

【问题讨论】:

  • 除了我的回答之外,我建议将最终的 map 更改为 for 循环。将副作用放在map 函数中并不是很好的风格,并且会导致借用问题,这在此处是不必要的。这是我将如何解决它:play.rust-lang.org/…
  • @PeterHall 谢谢你的建议。在阅读下面的答案后,我只是在尝试这种方法。再次感谢。

标签: rust char ascii predicate


【解决方案1】:

正如错误所说,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 的方法采用 &amp;self。对于非 ASCII 方法,您可以这样做,例如:

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

【讨论】:

  • 我刚刚查看了char::is_numericchar::is_ascii_punctuation 的签名,前者采用self,而后者采用&amp;self。至于为什么char的所有ascii方法都采用&amp;self而不是self,我不知道。尤其是这些方法似乎都在函数体中取消引用self
猜你喜欢
  • 2019-09-04
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-24
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多