【问题标题】:How can I box the contents of an iterator of a type that implements a trait?如何将实现特征的类型的迭代器的内容装箱?
【发布时间】:2018-06-19 04:27:29
【问题描述】:

我正在采用某种类型的迭代器,它必须实现特征 A,并尝试将其转换为 VecBoxes 的该特征:

trait A {}

fn test2<'a, I>(iterator: I) -> Vec<Box<A + 'a>>
where
    I: IntoIterator,
    I::Item: A + 'a,
{
    iterator
        .into_iter()
        .map(|a| Box::new(a))
        .collect::<Vec<Box<A + 'a>>>()
}

但是,编译失败,说:

error[E0277]: the trait bound `std::vec::Vec<std::boxed::Box<A + 'a>>: std::iter::FromIterator<std::boxed::Box<<I as std::iter::IntoIterator>::Item>>` is not satisfied
  --> src/main.rs:11:10
   |
11 |         .collect::<Vec<Box<A + 'a>>>()
   |          ^^^^^^^ a collection of type `std::vec::Vec<std::boxed::Box<A + 'a>>` cannot be built from an iterator over elements of type `std::boxed::Box<<I as std::iter::IntoIterator>::Item>`
   |
   = help: the trait `std::iter::FromIterator<std::boxed::Box<<I as std::iter::IntoIterator>::Item>>` is not implemented for `std::vec::Vec<std::boxed::Box<A + 'a>>`
   = help: consider adding a `where std::vec::Vec<std::boxed::Box<A + 'a>>: std::iter::FromIterator<std::boxed::Box<<I as std::iter::IntoIterator>::Item>>` bound

这种错误是有道理的,但是我不明白为什么以下内容没有问题:

fn test<'a, T: A + 'a>(t: T) -> Box<A + 'a> {
    Box::new(t)
}

这有什么不同?我如何表达我想将Box 他们设为As,而不是他们可能是什么类型?

【问题讨论】:

  • 当您按照错误消息中的两个“帮助”行进行操作时发生了什么?
  • @Shepmaster 会限制函数中可以使用的类型,不是吗?除非必要的 impl 恰好存在......

标签: iterator rust boxing


【解决方案1】:

您需要将Box&lt;I::Item&gt; 转换为Box&lt;A&gt;

fn test2<'a, I>(iterator: I) -> Vec<Box<dyn A + 'a>>
where
    I: IntoIterator,
    I::Item: A + 'a,
{
    iterator
        .into_iter()
        .map(|a| Box::new(a) as Box<dyn A>)
        .collect()
}

[直接返回Box::new]有什么不同?

作为Sven Marnach points out:

您不需要在函数中进行显式强制转换的原因是块的最后一条语句是一个强制转换站点,并且强制转换隐式地发生在这些站点上。详情请见the chapter on coercions in the nomicon

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-10-23
  • 1970-01-01
  • 2018-06-10
  • 1970-01-01
  • 2021-07-02
  • 2019-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多