首页 > 解决方案 > String::contains(String) 给出“特征绑定字符串:FnMut<(char,)>` 不满足”

问题描述

以下代码尝试检查 a 是否String包含另一个String. 使用该String::contains方法时出现编译器错误。我希望String::contains(String)开箱即用。

当正在搜索的模式不是字符串文字时,在 Rust 中执行此操作的正确方法是什么?我做到了rustc --explain E0277,似乎String没有实现该Pattern特征,是真的吗?

fn main() {
    let a = String::from("abcdefgh");
    let b = String::from("def");

    if a.contains(b) {
        println!("Contained");
    } else {
        println!("Not contained");
    }
}

编译器错误:

error[E0277]: the trait bound `std::string::String: std::ops::FnMut<(char,)>` is not satisfied
 --> src/main.rs:6:10
  |
6 |     if a.contains(b) {
  |          ^^^^^^^^ the trait `std::ops::FnMut<(char,)>` is not implemented for `std::string::String`
  |
  = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `std::string::String`

标签: stringrustcontains

解决方案


让我们检查一下方法签名str::contains

pub fn contains<'a, P>(&'a self, pat: P) -> bool 
where
    P: Pattern<'a>,

因此,正如您已经注意到的那样,第二个参数必须是实现的东西。Pattern我们可以通过访问. Pattern在那里我们可以找到这些实现:

impl<'a, 'b> Pattern<'a> for &'b str
impl<'a> Pattern<'a> for char
impl<'a, 'b> Pattern<'a> for &'b [char]
impl<'a, F> Pattern<'a> for F 
where
    F: FnMut(char) -> bool, 
impl<'a, 'b, 'c> Pattern<'a> for &'c &'b str
impl<'a, 'b> Pattern<'a> for &'b String

如您所见,该特征并未直接为String. 但它是为和实现的&String&str。这是有道理的:模式只需要被读取,因此String不需要所有权。

在您的示例中,您将无法使用b,因为它已被移入方法中:

let a: String = String::from("abcdefgh");
let b: String = String::from("def");

a.contains(b);

// If this would work, `b` couldn't be used anymore because it has been moved :(

因此,不要传递String( b),而是传递&String( &b)

if a.contains(&b) { ... }
//            ^

推荐阅读