如何在包含已经可迭代的项的结构上定义Rust中的迭代器?下面是对迭代器的一次尝试
use rand;
// Structure of items
struct Foo {
foo: Vec<f64>,
bar: Vec<i64>,
}
// Iterator for the structure
struct FooIter {
foo: Iterator,
bar: Iterator,
}
// Method that provides the iterator for use
impl Foo {
fn iter(&self) -> FooIter {
FooIter {
foo: self.foo.iter().peek(),
bar: self.bar.iter().peek(),
}
}
}
// Item desired from iterator
enum Bar {
MyFloat(f64),
MyInt(i64),
}
// Implementation of the iterator
impl Iterator for FooIter {
type Item = Bar;
fn next(&mut self) -> Option<Bar> {
match (self.foo.peek(), self.far.peek()) {
(Some(_), Some(_)) => {
if rand::random() {
self.foo.next()
} else {
self.bar.next()
}
}
(Some(_), None) => self.foo.next(),
(None, Some(_)) => self.bar.next(),
(None, None) => None,
}
}
}
// Iterate over a struct
fn main() {
let fuz = Foo {
foo: vec![1.2, 2.3, 3.4],
bar: vec![5, 6],
};
for item in fuz.iter() {
match item {
Bar::MyFloat(f) => println!("float : {}", f),
Bar::MyInt(i) => println!("int : {}", i),
}
}
}
简而言之,结构Foo
包含两个向量,我想要一个在这两个元素之间随机来回跳跃的迭代器。当然,这里有很多错误,但在核心部分,我不知道如何创建一个结构来承载foo
和far
项的迭代器,因为Rust将迭代器定义为特征而不是类型。
发布于 2019-06-05 17:29:07
@Stargateur在很大程度上对我进行了排序,但我想包括两个独立的代码来完成事情。以下是修复后的代码,它稍微接近于我最初的尝试,在Rust 1.34.1上工作:
// Structure of items
struct Foo {
foo: Vec<f64>,
far: Vec<i64>,
}
// Iterator for the structure
struct FooIter<FloatIter, IntIter>
where
FloatIter: Iterator<Item = f64>,
IntIter: Iterator<Item = i64>,
{
foo: std::iter::Peekable<FloatIter>,
far: std::iter::Peekable<IntIter>,
}
// Method that provides the iterator for use
impl Foo {
fn iter<'a>(
&'a self,
) -> FooIter<impl Iterator<Item = f64> + 'a, impl Iterator<Item = i64> + 'a> {
FooIter {
foo: self.foo.iter().cloned().peekable(),
far: self.far.iter().cloned().peekable(),
}
}
}
// Item desired from iterator
enum Bar {
MyFloat(f64),
MyInt(i64),
}
// Implementation of the iterator
impl<FloatIter, IntIter> Iterator for FooIter<FloatIter, IntIter>
where
FloatIter: Iterator<Item = f64>,
IntIter: Iterator<Item = i64>,
{
type Item = Bar;
fn next(&mut self) -> Option<Bar> {
match (self.foo.peek(), self.far.peek()) {
(Some(_), Some(_)) => {
if rand::random() {
self.foo.next().map(|x| Bar::MyFloat(x))
} else {
self.far.next().map(|x| Bar::MyInt(x))
}
}
(Some(_), None) => self.foo.next().map(|x| Bar::MyFloat(x)),
(None, Some(_)) => self.far.next().map(|x| Bar::MyInt(x)),
(None, None) => None,
}
}
}
// Iterate over a struct
fn main() {
let fuz = Foo {
foo: vec![1.2, 2.3, 3.4],
far: vec![5, 6],
};
for item in fuz.iter() {
match item {
Bar::MyFloat(f) => println!("float : {}", f),
Bar::MyInt(i) => println!("int : {}", i),
}
}
}
帮助我理解所发生的事情的是,FooIter
在泛型类型上参数化了它的参数。这些类型是通过在Foo
的iter
方法中的返回位置使用impl Trait
来推断的。也就是说,我能够编写类似的代码,而不使用下面的推论:
extern crate rand;
// Structure of items
struct Foo {
foo: Vec<f64>,
far: Vec<i64>,
}
// Iterator for the structure
struct FooIter<'a> {
foo: std::iter::Peekable<std::slice::Iter<'a, f64>>,
far: std::iter::Peekable<std::slice::Iter<'a, i64>>,
}
// Method that provides the iterator for use
impl Foo {
fn iter<'a>(&'a self) -> FooIter<'a> {
FooIter {
foo: self.foo.iter().peekable(),
far: self.far.iter().peekable(),
}
}
}
// Item desired from iterator
enum Bar {
MyFloat(f64),
MyInt(i64),
}
// Implementation of the iterator
impl<'a> Iterator for FooIter<'a> {
type Item = Bar;
fn next(&mut self) -> Option<Bar> {
match (self.foo.peek(), self.far.peek()) {
(Some(_), Some(_)) => {
if rand::random() {
self.foo.next().map(|x| Bar::MyFloat(x.clone()))
} else {
self.far.next().map(|x| Bar::MyInt(x.clone()))
}
}
(Some(_), None) => self.foo.next().map(|x| Bar::MyFloat(x.clone())),
(None, Some(_)) => self.far.next().map(|x| Bar::MyInt(x.clone())),
(None, None) => None,
}
}
}
// Iterate over a struct
fn main() {
let fuz = Foo {
foo: vec![1.2, 2.3, 3.4],
far: vec![5, 6],
};
for item in fuz.iter() {
match item {
Bar::MyFloat(f) => println!("float : {}", f),
Bar::MyInt(i) => println!("int : {}", i),
}
}
}
这几乎肯定是错误的做法,但我想看看这是否可能。我通过编译代码确定了迭代器类型:
fn main() {
let x = vec![1.2, 2.3, 3.4];
let y: i32 = x.iter().peekable();
}
这给了编译器错误:
error[E0308]: mismatched types
--> junk.rs:4:19
|
4 | let y: i32 = x.iter().peekable();
| ^^^^^^^^^^^^^^^^^^^ expected i32, found struct `std::iter::Peekable`
|
= note: expected type `i32`
found type `std::iter::Peekable<std::slice::Iter<'_, {float}>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
这包含了我正在寻找的类型。同样,这几乎肯定是错误的做法,但它帮助我理解了所提供的答案。
https://stackoverflow.com/questions/56412826
复制相似问题