【问题标题】:The trait `std::ops::Fn<(char,)>` is not implemented for `T``T` 没有实现特征`std::ops::Fn<(char,)>`
【发布时间】:2017-12-05 17:04:27
【问题描述】:

我正在尝试实现 greps 项目,但我卡在搜索功能上。

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
}

我收到此错误:

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`

为什么我需要 Fn 特征?添加该特征并不能解决我的问题。我正在使用泛型,我知道我在这里并不需要泛型,但我正在努力理解这个话题。

这里是 Rust playground 的完整代码。

【问题讨论】:

  • 错误信息非常令人困惑,并且与 AFAICT 无关;可能想要提交一个错误报告。真正的问题是str::contains() 想要一个具有the Pattern trait 的类型,但&amp;Path 没有实现该特征。 &amp;str 确实如此,所以 this 有效,但我不知道这是否真的是你想要的(因此发表评论而不是回答)......
  • 嘿,这确实解决了我的问题。 :D 一个疑问,这里为什么是查询路径?
  • 因为runwhere T: std::convert::AsRef&lt;std::path::Path&gt;

标签: generics rust traits


【解决方案1】:

问题(或其中之一)出在这个函数中:

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
}

函数line.contains() 需要一个实现特征Pattern 的参数。但是您的 T 参数不受约束。该错误有点令人困惑,因为您可能不关心FnFnOnce 实现,它们恰好是Pattern 的超类型。

您将面临的下一个问题是Pattern 本身尚未稳定,因此您不能显式使用它,除非您切换到编译器的夜间构建。否则,您可以约束T,使其至少可以变成已经实现Pattern 的其他东西,例如&amp;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
}

在此之后您仍然会遇到更多错误,但希望这可以帮助您克服最令人困惑的错误。

【讨论】:

    猜你喜欢
    • 2020-03-24
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多