2017-03-28 1 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

. ** 12 절 ** 어디에서 절이 ... 가장 이상하지 않느냐는 것이 드문 경우입니다. 또한 오류 메시지를 붙여 넣지 않기로 결정한 이유는 무엇입니까? – Shepmaster

+0

또한 "& ** 참고 **는 ** params 참조에서 아무 것도 ** ** 포함되지 않습니다 **, **"** 참고 **는'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를 사용 : 나는 * 강력하게 * A [MCVE]를하고 * 최소한의 * 측면에 작업 것을 검토하는 것이 좋습니다 것

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

다시 한번 고위급 특성 경계에 관한 독서를해야 할 것입니다. –

관련 문제