2016-06-14 3 views
1

벡터에 조각을 필터 :에있다 할 필요가있는 일의나는 구조체가

fn do_the_thing(foos: &[Foo]) { ... } 

부 :

enum Bar { 
    Bar0, 
    Bar1, 
    Bar2 
} 

struct Foo { 
    bar: Bar 
} 

을 나는 FOOS의 조각을받는 함수가 "바"에 대해 같은 값을 가질 슬라이스의 모든 요소에 다른 함수를 호출

fn another_func(foos: &[Foo]) { ... } 

내가 이런 식으로 뭔가를 시도 :

fn do_the_thing(foos: &[Foo]) { 
    let bar0_foos = foos.iter().filter(|f| f.bar == Bar0); 

    another_func(&bar0_foos); 
} 

비극적으로 bar0_foos는 &std::iter::Filter<std::slice::Iter<...>>입니다. 나는 또한 시도했다 : 여기

fn do_the_thing(foos: &[Foo]) { 
    let bar0_foos = foos.iter().filter(|f| f.bar == Bar0).collect(); 

    another_func(&bar0_foos); 
} 

, 나는 std::marker::Sized 만족 아니라고 말했다 해요.

그럼 어떻게해야할까요? 슬라이스가 아닌 다른 걸 가져 가야할까요? Iterator::collect는 제네릭 형식을 반환하기 때문에

답변

2

std::marker::Sized is not satisfied.

는, 컴파일러는 그 형태가 무엇을해야 알아 내기 위해 타입 추론을 사용합니다. 이 경우 bar0_foos에 대한 참조를 &[Foo]을 허용하는 함수에 전달하고 있습니다. 추론을 통해 bar0_foos[Foo]이어야합니다.

[Foo]은 크기가 정해져 있지 않으므로 해당 유형의 값을 만들 수 없습니다. Vec<T>가 작동 할 수있는,

error: mismatched types: 
expected `&[Foo]`, 
    found `&collections::vec::Vec<&Foo>` 
(expected slice, 
    found struct `collections::vec::Vec`) [E0308] 
<anon>:10  another_func(&bar0_foos); 
          ^~~~~~~~~~ 

오류 메시지가 여기에 오해의 소지가 작은 비트가이 오류를 제공

let bar0_foos: Vec<_> = // ... 

:

일반적으로, 당신은 수집의 종류에 수집 지정 &[T]으로 표시되므로 실제 문제는 아닙니다. 포함 된 유형이 문제입니다. Vec<&Foo> 콜렉션이 있지만 &[Foo]을 전달해야합니다.

논리적으로 오류가 발생합니다. 함수는 연속적인 범위 인 Foo을 나타내는 메모리 덩어리를 사용하지만 이는 사용자가 가지고있는 것이 아닙니다. 필터링을 통해 비 인접 데이터의 가능성이 있습니다. 또한 실제 데이터에 대한 포인터의 범위를 만들었습니다.

어떻게 수정합니까?

  1. another_func을 제어하는 ​​경우 &[&Foo]으로 변경하면됩니다.
  2. 당신은/

    fn another_func<F>(foos: &[F]) 
        where F: Borrow<Foo> 
    
  3. 당신은 복사 할 수 더 일반적인 것으로 변경 값을 복제하고 새로운 벡터를 만들 수 있습니다. 그런 다음 Vec<Foo>을 입력하면 &[Foo]으로 전달 될 수 있습니다.
  4. 입력 슬라이스의 순서를 변경하여 Foo을 모두 합친 다음 서브 슬라이스를 만들 수 있습니다.