我有一个结构:
enum Bar {
Bar0,
Bar1,
Bar2
}
struct Foo {
bar: Bar
}
我有一个功能需要一些Foos:
fn do_the_thing(foos: &[Foo]) { ... }
需要做的部分事情是在切片的所有元素上调用另一个函数,它们具有相同的值" bar":
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
不满意。
那么,这样做的正确方法是什么?我应该采取除切片以外的其他方式吗?
答案 0 :(得分:2)
std::marker::Sized
不满意。
由于Iterator::collect
返回泛型类型,编译器使用类型推断来确定该类型必须是什么。在这种情况下,您将对bar0_foos
的引用传递给接受&[Foo]
的函数。通过推理,这意味着bar0_foos
必须属于[Foo]
类型。
由于[Foo]
是未分类的类型,因此无法创建该类型的值。
通常,您可以指定要收集的集合类型:
let bar0_foos: Vec<_> = // ...
提供此错误:
error: mismatched types:
expected `&[Foo]`,
found `&collections::vec::Vec<&Foo>`
(expected slice,
found struct `collections::vec::Vec`) [E0308]
<anon>:10 another_func(&bar0_foos);
^~~~~~~~~~
错误消息在这里有点误导,因为Vec<T>
可以作为&[T]
运行,所以这不是真正的问题。包含的类型是问题:您有一个Vec<&Foo>
的集合,但需要传递&[Foo]
。
逻辑上,错误是有道理的。你的函数需要一大块代表{strong>连续范围Foo
的内存,但这不是你拥有的。通过过滤,您可以获得非连续数据。此外,您还创建了一系列指向实际数据的指针。
你如何解决?
another_func
,则可以将其更改为&[&Foo]
。 您可以将其更改为更通用的
fn another_func<F>(foos: &[F])
where F: Borrow<Foo>
Vec<Foo>
,可以作为&[Foo]
传入。Foo
放在一起,然后取一个子切片。