2017-03-28 40 views
0

我不知道在這裏問什麼適當的問題,但我有一個問題,獲得在一般方法中設置正確的生命週期。完整的代碼是here,但基本問題是我有一個類似於下面的方法,但是我得到了一生的錯誤。 &params引用中的任何內容都不會嵌入從.into()返回的結構中,因此這應該是安全的。我需要什麼來實現這個工作?正確的生命週期進入<Foo>參考作爲參數

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(); 
+0

我會*強烈*鼓勵回顧一下[MCVE]是什麼以及如何處理*最小*方面。某些指定** 12 **的地方......條款非常罕見,至少可以說。另外,你爲什麼決定不粘貼你得到的錯誤信息? – Shepmaster

+0

另外*「**從&參數引用將沒有任何**將**嵌入」*,與*「**沒有引用**將被嵌入到'R :: Attrs'中* – Shepmaster

+0

抱歉缺乏清晰度。我已經試圖將其剝離,我試圖進一步減少測試用例,但現在我看到你已經回答了我的問題。謝謝(並再次抱歉,我的蹩腳問題)! –

回答

2

你(我不知道你爲什麼不同意)錯誤:

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> 
{ 
+0

再次感謝,我看到我現在必須閱讀有關更高等級的特徵邊界的內容! –