2017-05-19 22 views
1

내가 사용하고자하는 최소한의 예제 라이브러리 코드가있다 :이 문제를 해결하는 방법은 "충분히 길지 않습니다"?

struct MyR<'a> { 
    x: &'a str, 
} 

struct T { 
    x: &'static str, 
} 

impl T { 
    fn bar<'a>(&'a self) -> MyR { 
     MyR { x: self.x } 
    } 
} 

는 IS 다음 내 코드 :

trait A<R, F: FnMut(&R)> { 
    fn foo(&mut self, callback: &mut F); 
} 

impl<'a, F> A<MyR<'a>, F> for T 
    where F: FnMut(&MyR<'a>) 
{ 
    fn foo(&mut self, callback: &mut F) { 
     let t = T { x: "l" }; 
     let r = t.bar(); // t does not live long enough (for 'a) 
     callback(&r); 
     println!("abc"); 
    } 
} 

fn test() { 
    let mut t = T { x: "l" }; 
    let mut i = 1; 
    t.foo(&mut |x| { i += x.x.len(); }); 
} 

내가 콜백에 의해 매개 변수화하는 특성을하고 싶지만 나는 그것을 옳게 만들기 위해 애썼다.

impl T { 
    fn foo<F: FnMut(&MyR)>(&mut self, callback: &'a mut F) { 
     let t = T { x: "l" }; 
     let r = t.bar(); 
     callback(&r); 
     println!("abc"); 
    } 
} 

그러나 나는이 작업을 수행 할 수 없습니다 : 나는 특성을 사용하지 않는 경우, 그것은 잘 작동

impl T { 
    fn foo<'a, F: FnMut(&MyR<'a>)>(&mut self, callback: &mut F) { 
     let t = T { x: "l" }; 
     let r = t.bar(); 
     callback(&r); 
     println!("abc"); 
    } 
} 

나는 문제가 t'a보다 오래해야한다는 것을 알지만, 나도 몰라 보다 짧아 지도록 'a에 바인딩합니다.

밤마다 rustc 1.19.0을 사용하고 있습니다.

답변

1

읽기 오류 메시지 :

  1. t

    가 충분히
    살지 않는 - 그것은 foo 기능이 끝날 때까지 살고있다.
  2. 빌린 값이 수명 '에 대해 유효해야합니다 - 당신은'a 지정한 :

    impl<'a, F> A<MyR<'a>, F> for T 
        where F: FnMut(&MyR<'a>) 
    

    가능한 수명를 들어, 특성이 너무 오래로 구현 될 것이라고 말했다 FFnMut 특성을 구현합니다.

은 그 일을 단지 수있는 방법은 - 당신이 'static 수명이 매개 변수가있는 MyR을 가지고 있습니다. 그것은 임의의 평생보다 오래 살아남을 수있는 유일한 수명입니다. 당신이 평생 사양 값을 제공하지 않는다는 점을 인식 것, 다시 가서 The Rust Programming Language section on lifetime elision 다시 읽어 경우

fn bar<'a>(&'a self) -> MyR { 
    MyR { x: self.x } 
} 

:

MyR이 어디에서 오는지 보자. 평생을 정의하고 self과 함께 사용하지만 출력 수명에는 전혀 영향을주지 않습니다. 당신이 수명을 제거한 경우

fn bar<'a, 'b>(&'a self) -> MyR<'b> 

는, 당신은

fn bar(&self) -> MyR 
fn bar<'a>(&'a self) -> MyR<'a> // equivalent 

그러나, 이들 중 어느 쪽도 'static 수명입니다 거라고 : 같은 코드는 동일합니다.다행히 당신을 위해, 당신은 x&'static str 것을 알고, 그래서 당신은 당신의 서명으로 그 사항을 반영 할 수 있으며 코드는 컴파일 :

fn bar(&self) -> MyR<'static> 
다른 접근을 시도하고,이 보인다
+0

나는 lib 디렉토리 코드를 변경할 수 없습니다입니다. 코드 만 바꿀 수 있습니다. 'fn foo (mut 자체, 콜백 : & 'a mut F)'와 같은 특성을 만들 수있는 방법이 없습니까? – colinfang

0

지출 시간 일을

trait A<F> { 
    fn foo(&mut self, callback: &mut F); 
} 

impl<F> A<F> for T 
    where F: FnMut(&MyR) 
{ 
    fn foo(&mut self, callback: &mut F) { 
     let t = T { x: "l" }; 
     let r = t.bar(); // t does not live long enough (for 'a) 
     callback(&r); 
     println!("abc"); 
    } 
} 

fn main() { 
    let mut t = T { x: "l" }; 
    let mut i = 1; 
    t.foo(&mut |x: &MyR| { i += x.x.len(); }); 

} 

주요 차이점은 다음

  • 난이 임의의 유형의 소요되도록 약간 느슨하게 형질한다.
  • 내가 임 플린 할 때 나는 평생을 전혀 지정할 필요가 없다.
  • 함수를 호출 할 때 클로저에 주석을 입력해야합니다.

Playground

관련 문제