2016-10-14 1 views
16

막연한 제목으로 미안하지만 녹이기가 매우 어렵습니다. 간결하게 내 문제를 요약하는 방법을 정확히 알지 못합니다. 나는 (최소한의 예를 나타내는) 뭔가를 구현하기 위해 노력하고있어컴파일러는 매개 변수 유형이 오래 지속되지 않을 수도 있기 때문에 '정적 수명'을 추가 할 것을 제안하지만 그게 내가 원하는 것 같지 않습니다.

은 다음과 같습니다

(지금까지 내가 말할 수있는) 패스에 의해 소유, 내 정신 모델은 생각에 녹 기본값 이후
trait Bar<T> {} 

struct Foo<T> { 
    data: Vec<Box<Bar<T>>> 
} 

impl<T> Foo<T> { 
    fn add<U: Bar<T>>(&mut self, x: U) { 
     self.data.push(Box::new(x)); 
    } 
} 

이게 효과가있다. add 메서드는 개체 x의 소유권을 가져 와서이 개체를 Box으로 옮길 수 있습니다.이 개체는 전체 형식 U을 알고 있으므로 (Bar<T>은 아님)이 개체를 이동할 수 있습니다. 상자 안으로 옮겨지면 상자 안의 항목 수명이 상자의 실제 수명과 연결되어야합니다 (예 : pop() 개체가 파괴 될 때).

그러나 컴파일러는 동의어에 동의하지 않으며 확실하다고 생각합니다. 'static 평생 한정자 (E0310) 추가를 고려해달라고 요청합니다. 나는 내가 원하는 바가 아니라는 것을 99 % 확신하지만, 나는 내가해야 할 일을 정확히 모르겠다.

내가 생각하고 무엇을 명확히하고 오해를 식별 할 수 있도록하기 위해, 내 모델 (I는 C++ 배경에서 온) 본질적 :

  • Box<T>은 본질적으로 어떤 주석없이 std::unique_ptr<T>
  • 이며, 변수에 의해 전달된다 Copy 값 및 기준 주석 달리
  • r- 수치 참조하면 & 대략 const&이고 &mut 대략 &
  • 이고
  • 기본 수명은

답변

14

확인 : 특히

error[E0310]: the parameter type `U` may not live long enough 
--> src/main.rs:9:24 
    | 
9 |   self.data.push(Box::new(x)); 
    |      ^^^^^^^^^^^ 
    | 
    = help: consider adding an explicit lifetime bound `U: 'static`... 
note: ...so that the type `U` will meet its required lifetime bounds 
--> src/main.rs:9:24 
    | 
9 |   self.data.push(Box::new(x)); 
    |      ^^^^^^^^^^^ 

, 컴파일러는 당신이 어떤 임의의 유형 U가 참조를 포함 할 수 있으며 그 기준은 다음 무효가 될 수있을 가능성이 있음을 알려주한다 :

impl<'a, T> Bar<T> for &'a str {} 

fn main() { 
    let mut foo = Foo { data: vec![] }; 

    { 
     let s = "oh no".to_string(); 
     foo.add(s.as_ref()); 
    } 
} 

나쁜 소식 일 것입니다.

'static 평생 또는 매개 변수가있는 평생을 원하는지 여부는 사용자의 요구에 달려 있습니다. 수명은 'static이지만 사용하기가 쉽지만 제한이 더 있습니다.당신이 구조체에 특성 객체 또는 유형 별칭 선언 할 때이 때문에 기본이다 : 그러나

struct Foo<T> { 
    data: Vec<Box<Bar<T>>>, 
    // same as 
    // data: Vec<Box<Bar<T> + 'static>>, 
} 

을 인수로 사용하는 경우, 형질 개체는 평생 생략를 사용하고 고유를 가져옵니다 평생 :

fn foo(&self, x: Box<Bar<T>>) 
// same as 
// fn foo<'a, 'b>(&'a self, x: Box<Bar<T> + 'b>) 

이 두 가지가 일치해야합니다.

struct Foo<'a, T> { 
    data: Vec<Box<Bar<T> + 'a>> 
} 

impl<'a, T> Foo<'a, T> { 
    fn add<U>(&mut self, x: U) 
     where U: Bar<T> + 'a 
    { 
     self.data.push(Box::new(x)); 
    } 
} 

또는

struct Foo<T> { 
    data: Vec<Box<Bar<T>>> 
} 

impl<T> Foo<T> { 
    fn add<U>(&mut self, x: U) 
     where U: Bar<T> + 'static 
    { 
     self.data.push(Box::new(x)); 
    } 
} 
+0

감사합니다. –

11

asking me to consider adding a 'static lifetime qualifier (E0310). I am 99% sure that's not what I want, but I'm not exactly sure what I'm supposed to do.

예 그것이 어휘 범위를합니다. 컴파일러에서 &'static 참조를 원하지 않는다면 U: 'static이 필요합니다.

U: 'static을 갖는 것은 U'static 미만의 수명을 가진 참조를 포함하지 않음을 의미합니다. 수명이없는 구조에 U 인스턴스를 넣으므로이 작업이 필요합니다. 전체 오류 밖으로

trait Bar<T> {} 

struct Foo<T> { 
    data: Vec<Box<Bar<T>>> 
} 

impl<T> Foo<T> { 
    fn add<U: Bar<T> + 'static>(&mut self, x: U) { 
     self.data.push(Box::new(x)); 
    } 
} 
+0

감사합니다! 그것은 매우 도움이되었습니다 - 나는 그의 대답이 더 완전하기 때문에 Shepmaster에게 받아 들여지는 대답을 줄 것입니다, 그러나 나는 그 해명에 감사드립니다! –

+1

@RobertMason 더 완벽했기 때문에 아무런 문제가 없었습니다. +1 답변했습니다. – mcarton

관련 문제