rust - 将引用作为参数更正 Into<Foo> 的生命周期

标签 rust lifetime

我不确定在这里问什么是合适的问题,但我对在通用方法中设置正确的生命周期有疑问。完整代码是 here ,但基本问题是我有一个类似于下面的方法,但我遇到了终身错误。 ¶ms 引用中的任何内容都不会嵌入到从 .into() 返回的结构中,因此这应该是安全的。我需要什么才能让它工作?

pub fn index<'a, T, R, P>(repository: T, query: &'a str) -> Result<Vec<<R as ToJson>::Attrs>, QueryStringParseError>
    where
        T: JsonApiRepository<'a, T = R>,
        P: 'a,
        R: ToJson,
        R: QueryString<'a, Params = P>,
        <R as ToJson>::Attrs: From<(R, &'a P)>,
        QueryStringParseError: From<<T as JsonApiRepository<'a>>::Error>
{
    let params = <R as QueryString>::from_str(query)?;
    let list = repository.find_all(&params)?;

    // What's the correct lifetime incantation for this to work?
    // No references will be embedded in `R::Attrs`, so this
    // should be safe
    let data: Vec<<R as ToJson>::Attrs> = list.into_iter().map(|e| (e, &params).into()).collect();
    Ok(data)
}

(修改后的问题,下面有错误)

rustc 1.16.0 (30cf806ef 2017-03-10)
error[E0373]: closure may outlive the current function, but it borrows `params`, which is owned by the current function
  --> <anon>:16:64
   |
16 |     let data: Vec<<R as ToJson>::Attrs> = list.into_iter().map(|e| (e, &params).into()).collect();
   |                                                                ^^^      ------ `params` is borrowed here
   |                                                                |
   |                                                                may outlive borrowed value `params`
   |
help: to force the closure to take ownership of `params` (and any other referenced variables), use the `move` keyword, as shown:
   |     let data: Vec<<R as ToJson>::Attrs> = list.into_iter().map(move |e| (e, &params).into()).collect();

最佳答案

你得到的错误(我不知道你为什么不分享):

error[E0373]: closure may outlive the current function, but it borrows `params`, which is owned by the current function
  --> src/main.rs:22:64
   |
22 |     let data: Vec<<R as ToJson>::Attrs> = list.into_iter().map(|e| (e, &params).into()).collect();
   |                                                                ^^^      ------ `params` is borrowed here
   |                                                                |
   |                                                                may outlive borrowed value `params`
   |
help: to force the closure to take ownership of `params` (and any other referenced variables), use the `move` keyword, as shown:
   |     let data: Vec<<R as ToJson>::Attrs> = list.into_iter().map(move |e| (e, &params).into()).collect();

您在函数内部创建了 params,但是所有特征边界都要求 params 的生命周期必须与从外部传入的字符串的生命周期相匹配。不可能满足该界限,并且看起来对 params 的引用必须通过闭包比函数存在的时间更长。因此,马马虎虎的错误信息。

您不应该将这些生命周期捆绑在一起。使用 higher-ranked trait bounds相反:

pub fn index<T, R, P, S, F>
    (repository: T,
     query: &str)
     -> Result<JsonApiArray<<R as ToJson>::Attrs>, QueryStringParseError>
    where T: JsonApiRepository<T = R>,
          P: Params,
          P: Default,
          P: TypedParams<SortField = S, FilterField = F>,
          P: for<'b> TryFrom<(&'b str, SortOrder, P), Err = QueryStringParseError>,
          P: for<'b> TryFrom<(&'b str, Vec<&'b str>, P), Err = QueryStringParseError>,
          R: ToJson,
          R: for<'b> QueryString<'b, Params = P, SortField = S, FilterField = F>,
          R: JsonApiResource<Params = P>,
          <R as ToJson>::Attrs: for<'b> From<(R, &'b P)>,
          QueryStringParseError: From<<T as JsonApiRepository>::Error>
{

关于rust - 将引用作为参数更正 Into<Foo> 的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43072710/

相关文章:

string - "Borrowed value does not live long enough", 在循环中使用时丢弃

rust - 将不可复制的拥有值传递给函数后尝试使用它们时会出现生命周期问题

rust - 扭曲和响应类型以及特征对象?

Rust 初始化泛型类型

rust - 如何在过程宏中处理枚举/结构/字段属性?

rust - 如何使用可变成员 Vec?

rust - 如何使用 Diesel 根据动态参数按列有条件地排序?

json - 是否可以使用 serde_json 反序列化看起来像 JSON(但不是)的数据?

.net - Windows Phone 8 应用程序生命周期事件和异步/等待

c++ - std::initializer_list 返回值的生命周期