2017-11-07 7 views
4

구조체 객체 컬렉션이 있습니다. 특성 개체의 반복자를 사용하여 컬렉션을 반복하고 싶습니다.하지만 적절한 반복기를 만들 수는 없습니다. 내 감소 된 테스트 코드는 다음과 같습니다특성 개체 참조의 반복자로서 구조체 컬렉션을 반복하는 방법은 무엇입니까?

struct MyStruct {} 
struct MyStorage(Vec<MyStruct>); 

trait MyTrait {} // Dummy trait to demonstrate the problem 
impl MyTrait for MyStruct {} 

trait MyContainer { 
    fn items<'a>(&'a self) -> Box<Iterator<Item = &'a MyTrait> + 'a>; 
} 
impl MyContainer for MyStorage { 
    fn items<'a>(&'a self) -> Box<Iterator<Item = &'a MyTrait> + 'a> { 
     Box::new(self.0.iter()) 
    } 
} 

이 다음과 같은 컴파일러 오류 발생 :

error[E0271]: type mismatch resolving `<std::slice::Iter<'_, MyStruct> as std::iter::Iterator>::Item == &MyTrait` 
    --> src/main.rs:12:9 
    | 
12 |   Box::new(self.0.iter()) 
    |   ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `MyStruct`, found trait MyTrait 
    | 
    = note: expected type `&MyStruct` 
       found type `&MyTrait` 
    = note: required for the cast to the object type `std::iter::Iterator<Item=&MyTrait>` 

나의 이해는 &MyStruct&MyTrait에 일반적으로 변환 될 수 있지만, 표준 라이브러리의 Iterator 구현은 허용하지 않는다는 것입니다을 이 경우에. 동일한 구문이 Vec<Box<MyStruct>>Iterator<Item=&Box<MyTrait>>과 함께 작동하지만 여기서는 복싱이 필요하지 않습니다.

참조로이 작업을 수행 할 수있는 방법이 있습니까?

+1

내가 확실하지 않았다,하지만 난 그것을 시도하고, 녹 (MyTrait + 'A)'와''& 사이의 차이를 볼 수 없습니다 & 'a MyTrait'이므로 두 번째 구문을 사용하는 것이 더 일반적인 구문이므로 사용해야합니다. – trentcl

답변

6

당신은 다음과 같이 명시 적으로 하나의 요소를 캐스팅해야합니다

Box::new(self.0.iter().map(|e| e as &MyTrait)) 
+0

감사합니다. 좋은 답변입니다! 런타임 (cpu, mem) 비용이 있습니까 아니면 "비 전통적인 캐스팅"입니까? –

+5

형질 객체 참조는 아마도 두 포인터가 크고 (하나는 객체에, 하나는 "vtable"), 간단한 포인터와 비교할 때 약간의 오버 헤드가 있지만 계산을 포함하면 안됩니다. 퍼포먼스 향상을 원한다면 iterator 주위의 Box를 제거해야한다. – Stefan