首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与`char::is_ascii_alphanumeric`匹配字符串失败,而`char::is_alphanumeric`编译

与`char::is_ascii_alphanumeric`匹配字符串失败,而`char::is_alphanumeric`编译
EN

Stack Overflow用户
提问于 2019-09-07 16:06:56
回答 1查看 879关注 0票数 2

我只想匹配字符串的字母数字ascii字符,但是matches函数只适用于is_alphanumeric。下面的例子应该加以澄清。我还把它放在生锈操场上,以便于复制。

代码语言:javascript
复制
fn main() {
    "s".matches(char::is_alphanumeric).collect(); // Works
    "s".matches(char::is_ascii_alphanumeric).collect(); // Doesn't work
}

产生了两个错误,第二个错误取决于第一个错误,我认为。错误消息声明:

代码语言:javascript
复制
error[E0631]: type mismatch in function arguments
 --> src/main.rs:3:9
  |
3 |     "s".matches(char::is_ascii_alphanumeric).collect(); // Doesn't work
  |         ^^^^^^^
  |         |
  |         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_alphanumeric}`

error[E0599]: no method named `collect` found for type `std::str::Matches<'_, for<'r> fn(&'r char) -> bool {std::char::methods::<impl char>::is_ascii_alphanumeric}>` in the current scope
 --> src/main.rs:3:46
  |
3 |     "s".matches(char::is_ascii_alphanumeric).collect(); // Doesn't work
  |                                              ^^^^^^^
  |
  = note: the method `collect` exists but the following trait bounds were not satisfied:
          `&mut std::str::Matches<'_, for<'r> fn(&'r char) -> bool {std::char::methods::<impl char>::is_ascii_alphanumeric}> : std::iter::Iterator`
          `std::str::Matches<'_, for<'r> fn(&'r char) -> bool {std::char::methods::<impl char>::is_ascii_alphanumeric}> : std::iter::Iterator`

有人能向我解释一下,这个错误意味着什么,为什么它适用于一个函数而不是另一个函数?我查看了这两个函数的类型签名,但它们在我看来是一样的:

我使用的是Rust v1.37.0

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-07 17:04:34

为什么它适用于一种功能,而不是另一种?

让我们来看看签名:

代码语言:javascript
复制
fn       is_alphanumeric( self) -> bool
fn is_ascii_alphanumeric(&self) -> bool

一个函数接受&self (一个引用),另一个函数以self (按值)作为参数。在这种情况下,这是一个重要的区别。现在让我们再次检查错误:

代码语言:javascript
复制
error[E0631]: type mismatch in function arguments
 --> src/main.rs:3:9
  |
3 |     "s".matches(char::is_ascii_alphanumeric).collect(); // Doesn't work
  |         ^^^^^^^
  |         |
  |         expected signature of `fn(char) -> _`
  |         found signature of `for<'r> fn(&'r char) -> _`

特别是最后一部分(由我调整):

代码语言:javascript
复制
  |         expected signature of `        fn(    char) -> _`
  |         found signature of    `for<'r> fn(&'r char) -> _`

它表明了一个以char为参数的函数是预期的,但找到了一个以&'r char为参数的函数。忽略这里的for<'r>'r,它们在本例中并不重要。

为什么fn(char)会被期待?那么,看看str::matches,它就会显示它接受任何实现Pattern的东西。在Pattern的实现者中,我们发现:

代码语言:javascript
复制
impl<'a, F> Pattern<'a> for F
where
    F: FnMut(char) -> bool,

这也是为什么期望一个函数通过值而不是引用来获取char的原因。

你怎么能修好它?您可以始终提供一个闭包,只需使用引用的值调用该方法。这可能没有任何运行时开销,因为优化器很容易将闭包内联起来。

代码语言:javascript
复制
"s".matches(|c| char::is_ascii_alphanumeric(&c))

还有几件事:

  • 第二个错误消息只是第一个错误的结果。它在应用修复后就消失了。
  • 您仍然需要指定要将迭代器收集到的集合的类型。例如,Vec<_>:let x: Vec<_> =“s”.matches(x,c= char::is_ascii_alphanumeric(&c)).collect();
  • 为什么这两种char方法有不同的签名?!这似乎很奇怪,实际上,两者都倾向于采用self的价值。巧合的是,是我在is_ascii_alphanumeric中直接将char添加到这个公关中。这与养大不一致,我解释了这种奇怪的原因,这里。 原因很简单,就是这个方法刚刚从一个旧的AsciiExt特性中移开。这一特点现在已不受欢迎了。可悲的是,该方法在服用&self时已经稳定下来。将方法移动到char很好,但是添加签名会破坏代码。所以&self的签名被保留了下来。简单回答:向后兼容性。我还发现了本期,在那里有人尝试了几乎和你一样的尝试。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57835391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档