2017-01-17 8 views
1

각 분기가 다른 유형을 반환 할 수있는 일치를 실행하려고하는 코드가 있지만 이 유형은 모두 Iterator<Item=usize>을 구현합니다. 반복자를 반환하는 팔을 일치 시킵니까?

let found: Iterator<Item = usize> = match requirements { 
    Requirements::A => MatchingAs { ainternals: [] }, 
    Requirements::B => MatchingBs { binternals: [] }, 
    Requirements::C => MatchingCs { cinternals: [] }, 
}; 

return found.any(|m| m == 1) 

... 어디 MatchingAs, MatchingBsMatchingCs 모든 impl std::iter::Iterator<Item = usize>.

나는 Iterator이 크기되지 않는다는 사실과 벽 타격 해요 :

| the trait `std::marker::Sized` is not implemented for `std::iter::Iterator<Item=usize>` 

를 매치 팔이 공유 특성과 개체를 반환하고 의지가 할 수있는 좋은 방법이 있나요 (만) 결과를 처리하는 특성에?

+1

이것이 [반복자를 반환하는 올바른 방법]과 중복되지 않는 이유를 설명하십시오. (http://stackoverflow.com/q/27535289/155423) – Shepmaster

답변

4

당신이 Sized없는 무언가를 반환 할 첫 번째 반사, 그것은 (일명, 포인터를 힙에 넣어 반환) Box이다 :

이 여기에, 충분하지
let found: Box<Iterator<Item = usize>> = match requirements { 
    Requirements::A => Box::new(MatchingAs { ainternals: [] }), 
    Requirements::B => Box::new(MatchingBs { binternals: [] }), 
    Requirements::C => Box::new(MatchingCs { cinternals: [] }), 
}; 

found.any(|m| m == 1) 

, 지금 match는 서로 다른 유형의 반환 불평 때문에 그래서, impl Trait for Concrete이있을 때마다 Box<MatchingAs>, Box<MatchingBs>을 ...

그러나, Box<Concrete>Box<Trait>에 캐스트 할 수 있습니다

사용 제네릭 :
let found = match requirements { 
    Requirements::A => Box::new(MatchingAs { ainternals: [] }) as Box<Iterator<Item = usize>>, 
    Requirements::B => Box::new(MatchingBs { binternals: [] }) as Box<Iterator<Item = usize>>, 
    Requirements::C => Box::new(MatchingCs { cinternals: [] }) as Box<Iterator<Item = usize>>, 
}; 

found.any(|m| m == 1) 

는하지만, 할당이없는 솔루션이 있습니다.

fn search<T: Iterator<Item = usize>>(t: T) -> bool { 
    t.any(|m| m == 1) 
} 

다음은 match의 각 지점에 해당 기능을 적용

match requirements { 
    Requirements::A => search(MatchingAs {ainternals: []}), 
    Requirements::B => search(MatchingBs {binternals: []}), 
    Requirements::C => search(MatchingCs {cinternals: []}), 
} 

트레이드 오프가 콜백 - 지옥을 위해, 다소 간접적 인 흐름을 조금 더 가까이 있다는 것입니다.