简体   繁体   中英

The trait `std::ops::Fn<(char,)>` is not implemented for `T`

I am trying to implement the greps project and I am stuck at the search function.

fn search<'a, T>(query: &T, contents: &'a str) -> Vec<&'a str> {
    let mut results = Vec::new();

    for line in contents.lines() {
        if line.contains(query) {
            results.push(line);
        }
    }
    results
}

I am getting this error:

rustc 1.18.0 (03fc9d622 2017-06-06)
error[E0277]: the trait bound `T: std::ops::Fn<(char,)>` is not satisfied
  --> <anon>:39:17
   |
39 |         if line.contains(query) {
   |                 ^^^^^^^^ the trait `std::ops::Fn<(char,)>` is not implemented for `T`
   |
   = help: consider adding a `where T: std::ops::Fn<(char,)>` bound
   = note: required because of the requirements on the impl of `std::ops::FnOnce<(char,)>` for `&T`
   = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&T`

error[E0277]: the trait bound `T: std::ops::FnOnce<(char,)>` is not satisfied
  --> <anon>:39:17
   |
39 |         if line.contains(query) {
   |                 ^^^^^^^^ the trait `std::ops::FnOnce<(char,)>` is not implemented for `T`
   |
   = help: consider adding a `where T: std::ops::FnOnce<(char,)>` bound
   = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&T`

error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
  --> <anon>:57:40
   |
57 |         assert_eq!(vec!["KAMEHAMEHA"], search(query, contents));
   |                                        ^^^^^^ the trait `std::marker::Sized` is not implemented for `str`
   |
   = note: `str` does not have a constant size known at compile-time
   = note: required by `search`

Why do I need the Fn trait? Adding that trait isn't solving my problem. I am using generics, and I know I don't really need generics here but I am trying to understand the topic.

Here is the full code on Rust playground .

The problem (or one of them) is in this function:

fn search<'a, T>(query: &T, contents: &'a str) -> Vec<&'a str> {
    let mut results = Vec::new();

    for line in contents.lines() {
        if line.contains(query) {
            results.push(line);
        }
    }
    results
}

The function line.contains() expects an argument that implements the trait Pattern . But your T parameter is unconstrained. The error is a little confusing because you probably don't care about the Fn and FnOnce implementations, which just happen to be supertypes of Pattern .

The next problem you'll face is that Pattern itself is not stabilized yet, so you can't use it explicitly unless you switch to a nightly build of the compiler. Otherwise, you can constrain T so that it can at least be turned into something else that already implements Pattern , such as &str :

fn search<'a, T: 'a>(query: &'a T, contents: &'a str) -> Vec<&'a str> 
    where &'a T: Into<&'a str>
{
    let mut results = Vec::new();

    for line in contents.lines() {
        if line.contains(query.into()) {
            results.push(line);
        }
    }
    results
}

You'll still have more errors after this, but hopefully this gets you past the most confusing one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM