2017-10-23 10 views
0

이것은 현재 직면 한 문제의 단순화 된 버전입니다. 개체 풀에서 차용 할 때 생략 된 정적 수명 해결

trait SuperObject { 
    fn object_name(&self) -> String; 
} 

trait Inspect { 
    fn inspect(&self); 
} 

impl Inspect for SuperObject { 
    fn inspect(&self) { 
     println!("I am a Superobject."); 
    } 
} 

struct Object { 
    name: String 
} 

impl SuperObject for Box<Object> { 
    fn object_name(&self) -> String { 
     format!("I am {}.", self.name.clone()) 
    } 
} 

struct ObjectPool { 
    object1: Box<Object>, 
    object2: Box<Object>, 
    object3: Box<Object> 
} 

impl ObjectPool { 
    pub fn new() -> ObjectPool { 
     ObjectPool { 
      object1: Box::new(Object { name: String::from("Object 1") }), 
      object2: Box::new(Object { name: String::from("Object 2") }), 
      object3: Box::new(Object { name: String::from("Object 3") }) 
     } 
    } 
    fn all_objects(&self) -> Vec<&SuperObject> { 
     let mut ret: Vec<&SuperObject> = Vec::new(); 
     ret.push(&self.object1); 
     ret.push(&self.object2); 
     ret.push(&self.object3); 
     ret 
    } 
} 

fn main() { 
    let objectpool: ObjectPool = ObjectPool::new(); 
    let allobjects: Vec<&SuperObject> = objectpool.all_objects(); 
    for i in &allobjects { 
     println!("{}", i.object_name()); 
     // Comment the following line in order to drop error E0597 
     i.inspect(); // FIXME: borrowed value must be valid for the static lifetime 
    } 
} 

다음과 같이이 코드를 컴파일하려고 오류 : 내가 이해 기본 고정 수명이 https://doc.rust-lang.org/book/second-edition/ch19-02-advanced-lifetimes.html

에 언급, 객체가 인스턴스화되는 많은 검색 후

error[E0597]: `objectpool` does not live long enough 
    --> src/main.rs:50:41 
    | 
50 |  let allobjects: Vec<&SuperObject> = objectpool.all_objects(); 
    |           ^^^^^^^^^^ does not live long enough 
... 
56 | } 
    | - borrowed value only lives until here 
    | 
    = note: borrowed value must be valid for the static lifetime... 

error: aborting due to previous error 

을,

ObjectPool의 all_objects 메소드의 출력이 스 니펫 디버깅을 시도 할 때 발생하는 오류 중 하나에 의해 입증 된 바와 같이 정적으로 컴파일러에 의해 제거되었다고 생각합니다.

error[E0308]: mismatched types 
    --> src/main.rs:42:18 
    | 
42 |   ret.push(&self.object2); 
    |     ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found reference 
    | 
    = note: expected type `std::boxed::Box<SuperObject>` 
       found type `&std::boxed::Box<SuperObject + 'static>` 

개체 풀을 모두 폐기하는 것이 가장 좋은 조치는 무엇입니까? 아니면 녹 구현에 적합한 더 우아한 추상화가 있습니까?

답변

3

문제는 impl Inspect for SuperObject입니다. 다른 특성을위한 특성을 구현하면 이 아니라이 기대하는 바를 수행합니다. 기본적으로 규칙은 : 그것을하지 마십시오. 본질적으로 이는 &(SuperObject + 'static)이있을 때만 Inspect으로 처리 할 수 ​​있음을 의미합니다. 원하는 것은 무엇입니까

impl<T: SuperObject + ?Sized> Inspect for T { 
    fn inspect(&self) { 
     println!("I am a Superobject."); 
    } 
} 
+0

좋아요, 제네릭을 다듬을 필요가 있습니다. 위의 솔루션에서 이제 Inspect 구현은 SuperObject에서만 허용됩니다. 예를 들어 SuperObject (예 : OtherSuperObject) 이외의 구조체에 대해 Inspect를 사용하려고하면 가능하지 않습니다. 그게 맞습니까? 이 경우 해결 방법이 있습니까? –

+0

그래, 문제가있어. 나는 그것을 고치는 방법을 모르겠다. 그러나 대개 나는 그런 상황에서 녹에 대한 다형성 디자인을 강요하고 녹슬지 않는 방식으로 디자인을 재 작업 한 후 모든 작업을해야한다는 것을 알았습니다. –