如何将实现特征的类型的迭代器的内容装箱? [英] How can I box the contents of an iterator of a type that implements a trait?

查看:14
本文介绍了如何将实现特征的类型的迭代器的内容装箱?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

特征 A {}fn test2<'a, I>(迭代器:I) ->Vec<Box<A + 'a>>在哪里我:进入迭代器,我::项目: A + 'a,{迭代器.into_iter().map(|a| Box::new(a)).collect::<Vec<Box<A + 'a>>>()}

但是,编译失败,说:

error[E0277]: trait bound `std::vec::Vec

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

fn test<'a, T: A + 'a>(t: T) ->方框<A + 'a>{盒子::新(t)}

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

解决方案

你需要将Box转换成Box:

fn test2<'a, I>(iterator: I) ->Vec<Box<dyn A + 'a>>在哪里我:进入迭代器,我::项目: A + 'a,{迭代器.into_iter().map(|a| Box::new(a) as Box).搜集()}

<块引用>

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

作为 Sven Marnach 指出:

<块引用>

您不需要在函数中进行显式强制转换的原因是块的最后一条语句是一个强制转换站点,并且强制转换隐式地发生在这些站点上.有关详细信息,请参阅有关 nomicon 中的强制转换的章节.

I'm taking an iterator of some type that must implement the trait A, and trying to convert it into a Vec of Boxes of that trait:

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>>>()
}

However, this fails to compile, saying:

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

This error kind of makes sense, but then I don't see why there's no problem with the following:

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

How is that any different? How can I express that I'd like to Box them as As, rather than whatever type they may be?

解决方案

You need to cast the Box<I::Item> into a Box<A>:

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()
}

How is [returning Box::new directly] any different?

As Sven Marnach points out:

The reason why you don't need an explicit cast in the function is that the last statement of a block is a coercion site and coercions happen implicitly at these sites. See the chapter on coercions in the nomicon for further details.

这篇关于如何将实现特征的类型的迭代器的内容装箱?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆