【问题标题】:Clonable iterator trait object可克隆的迭代器特征对象
【发布时间】:2016-02-13 10:01:03
【问题描述】:

我正在尝试使用可克隆的迭代器对象定义结构。到目前为止,我已经达到了:

pub struct UseClonableIterator2<'a,T:'a> {
    it: &'a (Iterator<Item=T> + Clone)
}

因为Clone 不是“内置特征”而无法编译:

x.rs:2:33: 2:38 error: only the builtin traits can be used as closure or object bounds [E0225]
x.rs:2     it: &'a (Iterator<Item=T> + Clone)
                                       ^~~~~           
x.rs:2:33: 2:38 help: run `rustc --explain E0225` to see a detailed explanation

一个选项可能是为迭代器添加另一个类型参数,但这会使定义复杂化,我宁愿避免它。

【问题讨论】:

    标签: rust


    【解决方案1】:

    您需要动态调度吗?如果不是,您应该使用泛型参数而不是特征对象——它不一定会使定义复杂化。试试这个例子:

    pub struct UseClonableIterator<I: Iterator + Clone> {
        it: I
    }
    

    在这里,您可以在您的类型中保存实现IteratorClone 的对象。如果你只是想引用它,这当然也是可以的:

    pub struct UseClonableIterator2<'a, I: Iterator + Clone + 'a> {
        it: &'a I
    }
    

    请注意,在这两个示例中,我们都使用了静态调度和单态化。这通常会带来更好的性能。

    但是,这并不总是可行的——有时需要使用 trait 对象进行动态调度(就像您尝试实现它一样)。在这种情况下,您只能通过重构代码来解决问题,因为 Rust 还不允许具有多个特征的特征对象。

    【讨论】:

      【解决方案2】:

      如果您需要动态调度迭代器,即Iterator 实现类型不能是UseClonableIterator 的类型参数,那么我将使用我的dyn-clone crate 解决此问题。


      use dyn_clone::{clone_trait_object, DynClone};
      
      trait ClonableIterator: Iterator + DynClone {}
      
      impl<I: Iterator + DynClone> ClonableIterator for I {}
      
      clone_trait_object!(<T> ClonableIterator<Item = T>);
      
      #[derive(Clone)]
      struct UseClonableIterator<T> {
          it: Box<dyn ClonableIterator<Item = T>>,
      }
      
      fn main() {
          let thing1 = UseClonableIterator {
              it: Box::new(vec![1, 2, 3].into_iter()),
          };
      
          let thing2 = thing1.clone();
      
          // prints 1 2 3 from thing1's iterator
          for i in thing1.it {
              println!("{}", i);
          }
      
          // prints 1 2 3 from thing2's iterator
          for i in thing2.it {
              println!("{}", i);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-10-23
        • 2011-07-10
        • 1970-01-01
        • 2016-08-27
        • 2015-08-01
        • 2020-02-10
        • 1970-01-01
        • 2012-01-06
        相关资源
        最近更新 更多