首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以将IntoIterator类型的特征对象装箱并保存在结构中?

是否可以将IntoIterator类型的特征对象装箱并保存在结构中?
EN

Stack Overflow用户
提问于 2020-11-05 11:53:05
回答 1查看 173关注 0票数 3

是否可以将IntoIterator类型的特征对象装箱并保存在结构中?我有一种情况,我想存储一个可以转换为迭代器的对象的向量。我对此的尝试是代码

代码语言:javascript
复制
struct Foo {   
    foo: Vec<Box<dyn IntoIterator<Item = usize>>>,
}                                                            
                 
fn main() {                                                                     
    let _ = Foo {                                                               
        foo: vec![Box::new(1..2), Box::new(vec![2,4,4])],                       
    };                                                                          
}

但是,这不会编译并产生以下错误:

代码语言:javascript
复制
error[E0191]: the value of the associated type `IntoIter` (from trait `IntoIterator`) must be specified
 --> src/main.rs:6:22
  |
6 |     foo: Vec<Box<dyn IntoIterator<Item = usize>>>,
  |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `IntoIterator<Item = usize, IntoIter = Type>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0191`.

我知道,大多数时候,当我们想使用IntoIterator时,我们会将泛型传递到结构中。然而,在这种情况下,我想存储的项目没有相同的时间。因此,有没有一种方法可以存储异构的对象集合,这些对象集合都可以转换为相同类型的迭代器?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-05 12:43:08

你想做的事对我来说没有多大意义。但是,可以很容易地装箱每个Iterator而不是每个IntoIterator

代码语言:javascript
复制
struct Foo {   
    foo: Vec<Box<dyn Iterator<Item = usize>>>,
}                                                            
                 
fn main() {                                                                     
    let _ = Foo {                                                               
        foo: vec![Box::new((1..2).into_iter()), Box::new(vec![2,4,4].into_iter())],                       
    };                                                                          
}

你遇到的问题是IntoIterator是这样定义的:

代码语言:javascript
复制
pub trait IntoIterator {
    type Item;
    type IntoIter: Iterator<Item = Self::Item>;
    fn into_iter(self) -> Self::IntoIter;
}

为了让编译器发出单态代码,您必须在foo字段的声明中的dyn说明符中指定Item类型和IntoIter类型。但是实现IntoIterator的不同类型具有不同的IntoIter类型。

如果在将IntoIterator对象实际转换为Iterator之前将其装箱对您来说真的很重要,那么您必须添加一个新的包装器来将所有不同的IntoIter类型转换为Box<dyn Iterator>。如下所示:

代码语言:javascript
复制
use std::iter::IntoIterator;

struct GenericIntoIterator<I: IntoIterator>(I);

impl<I: 'static + IntoIterator> std::iter::IntoIterator for GenericIntoIterator<I>
{
    type Item = <I as IntoIterator>::Item;
    type IntoIter = Box<dyn 'static + Iterator<Item = Self::Item>>;
    fn into_iter(self) -> Self::IntoIter {
        Box::new(self.0.into_iter())
    }
}

struct Foo {   
    foo: Vec<Box<dyn 'static + IntoIterator<Item = usize, IntoIter = Box<dyn 'static + Iterator<Item=usize>>>>>,
}                                                            
                 
fn main() {                                                                     
    let _ = Foo {                                                               
        foo: vec![Box::new(GenericIntoIterator(1..2)), Box::new(GenericIntoIterator(vec![2,4,4]))],                       
    };                                                                          
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64690981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档