如何将实现特征的类型的迭代器的内容装箱?
How can I box the contents of an iterator of a type that implements a trait?
我正在使用某种类型的迭代器,它必须实现特征 A
,并试图将其转换为具有该特征的 Box
es 的 Vec
:
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
它们作为 A
,而不是它们可能是什么类型?
您需要将 Box<I::Item>
转换为 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?
作为:
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.
我正在使用某种类型的迭代器,它必须实现特征 A
,并试图将其转换为具有该特征的 Box
es 的 Vec
:
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
它们作为 A
,而不是它们可能是什么类型?
您需要将 Box<I::Item>
转换为 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?
作为
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.