如何创建一个带有迭代器的结构?
How can I create a struct that takes an iterator?
我想创建一个可以容纳任何类型的迭代器的结构。我的实际代码的简化尝试如下:
struct MyStruct<I> {
my_iter: I,
}
impl<I> MyStruct<I>
where
I: std::iter::Iterator<Item = usize>,
{
fn new(start: usize) -> Self {
let v: Vec<usize> = vec![start+1, start+2, start+3];
Self {
my_iter: v.iter().map(|n| n*2),
}
}
}
不幸的是,我在编译时遇到以下错误:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:12:22
|
5 | impl<I> MyStruct<I>
| - this type parameter
...
12 | my_iter: v.iter().map(|n| n*2),
| ^^^^^^^^^^^^^^^^^^^^^ expected type parameter `I`, found struct `Map`
|
= note: expected type parameter `I`
found struct `Map<std::slice::Iter<'_, usize>, [closure@src/main.rs:12:35: 12:42]>`
error[E0284]: type annotations needed: cannot satisfy `<_ as Iterator>::Item == usize`
--> src/main.rs:18:13
|
18 | let _ = MyStruct::new(2);
| ^^^^^^^^^^^^^ cannot satisfy `<_ as Iterator>::Item == usize`
|
note: required by a bound in `MyStruct::<I>::new`
--> src/main.rs:7:28
|
7 | I: std::iter::Iterator<Item = usize>,
| ^^^^^^^^^^^^ required by this bound in `MyStruct::<I>::new`
8 | {
9 | fn new(start: usize) -> Self {
| --- required by a bound in this
Some errors have detailed explanations: E0284, E0308.
For more information about an error, try `rustc --explain E0284`.
error: could not compile `playground` due to 2 previous errors
我无法从错误中弄清楚如何得到我想要的。
您的实现有两个问题:
.iter()
方法借用vec,因此您试图存储对局部变量的引用,这是不正确的(在释放后使用)
- 泛型是从“外部”驱动的,但您想从函数内部指定它们,这是不可能的。
因此,一种选择是使用盒装迭代器。这将允许您从函数体中指定它,还可以使用 any 迭代器:
struct MyStruct {
my_iter: Box<dyn Iterator<Item = usize>>,
}
impl MyStruct {
fn new(start: usize) -> Self {
let v: Vec<usize> = vec![start + 1, start + 2, start + 3];
Self {
// note that we are using `.into_iter()` which does not borrow the vec, but converts it to an iterator!
my_iter: Box::new(v.into_iter().map(|n| n * 2)),
}
}
}
如果您坚持使用泛型,另一种选择是从外部传递迭代器:
use std::marker::PhantomData;
struct MyStruct<'l, I> {
my_iter: I,
_phantom: PhantomData<&'l I>,
}
impl<'l, I> MyStruct<'l, I>
where
I: std::iter::Iterator<Item = usize> + 'l,
{
fn new(iter: I) -> Self {
Self {
my_iter: iter,
_phantom: Default::default(),
}
}
}
fn main() {
let mut data = vec![1, 2, 3];
let x = MyStruct::new(data.iter().map(|x| *x + 1));
}
我想创建一个可以容纳任何类型的迭代器的结构。我的实际代码的简化尝试如下:
struct MyStruct<I> {
my_iter: I,
}
impl<I> MyStruct<I>
where
I: std::iter::Iterator<Item = usize>,
{
fn new(start: usize) -> Self {
let v: Vec<usize> = vec![start+1, start+2, start+3];
Self {
my_iter: v.iter().map(|n| n*2),
}
}
}
不幸的是,我在编译时遇到以下错误:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:12:22
|
5 | impl<I> MyStruct<I>
| - this type parameter
...
12 | my_iter: v.iter().map(|n| n*2),
| ^^^^^^^^^^^^^^^^^^^^^ expected type parameter `I`, found struct `Map`
|
= note: expected type parameter `I`
found struct `Map<std::slice::Iter<'_, usize>, [closure@src/main.rs:12:35: 12:42]>`
error[E0284]: type annotations needed: cannot satisfy `<_ as Iterator>::Item == usize`
--> src/main.rs:18:13
|
18 | let _ = MyStruct::new(2);
| ^^^^^^^^^^^^^ cannot satisfy `<_ as Iterator>::Item == usize`
|
note: required by a bound in `MyStruct::<I>::new`
--> src/main.rs:7:28
|
7 | I: std::iter::Iterator<Item = usize>,
| ^^^^^^^^^^^^ required by this bound in `MyStruct::<I>::new`
8 | {
9 | fn new(start: usize) -> Self {
| --- required by a bound in this
Some errors have detailed explanations: E0284, E0308.
For more information about an error, try `rustc --explain E0284`.
error: could not compile `playground` due to 2 previous errors
我无法从错误中弄清楚如何得到我想要的。
您的实现有两个问题:
.iter()
方法借用vec,因此您试图存储对局部变量的引用,这是不正确的(在释放后使用)- 泛型是从“外部”驱动的,但您想从函数内部指定它们,这是不可能的。
因此,一种选择是使用盒装迭代器。这将允许您从函数体中指定它,还可以使用 any 迭代器:
struct MyStruct {
my_iter: Box<dyn Iterator<Item = usize>>,
}
impl MyStruct {
fn new(start: usize) -> Self {
let v: Vec<usize> = vec![start + 1, start + 2, start + 3];
Self {
// note that we are using `.into_iter()` which does not borrow the vec, but converts it to an iterator!
my_iter: Box::new(v.into_iter().map(|n| n * 2)),
}
}
}
如果您坚持使用泛型,另一种选择是从外部传递迭代器:
use std::marker::PhantomData;
struct MyStruct<'l, I> {
my_iter: I,
_phantom: PhantomData<&'l I>,
}
impl<'l, I> MyStruct<'l, I>
where
I: std::iter::Iterator<Item = usize> + 'l,
{
fn new(iter: I) -> Self {
Self {
my_iter: iter,
_phantom: Default::default(),
}
}
}
fn main() {
let mut data = vec![1, 2, 3];
let x = MyStruct::new(data.iter().map(|x| *x + 1));
}