稳定锈
您可以为您感兴趣的每个独特的trait对象创建和实现trait:
trait Shipyard {
fn construct(boat: Boat) -> Box<Self>;
}
impl Shipyard for Boat {
fn construct(boat: Boat) -> Box<Self> {
Box::new(boat)
}
}
impl Shipyard for Vehicle {
fn construct(boat: Boat) -> Box<Vehicle> {
Box::new(boat) as Box<Vehicle>
}
}
impl Shipyard for Floating {
fn construct(boat: Boat) -> Box<Floating> {
Box::new(boat) as Box<Floating>
}
}
fn populate<T: ?Sized>(receiver: &mut Vec<Box<T>>)
where
T: Shipyard,
{
receiver.push(T::construct(Boat));
}
宏可以删除重复项。
夜锈
你可以用不稳定的
CoerceUnsized
特质:
#![feature(coerce_unsized)]
use std::ops::CoerceUnsized;
fn populate<T: ?Sized>(receiver: &mut Vec<Box<T>>)
where
Box<Boat>: CoerceUnsized<Box<T>>,
{
receiver.push(Box::new(Boat) as Box<T>);
}
相当于:
#![feature(unsize)]
use std::marker::Unsize;
fn populate<T: ?Sized>(receiver: &mut Vec<Box<T>>)
where
Boat: Unsize<T>,
{
receiver.push(Box::new(Boat) as Box<T>);
}
你可以追踪他们的稳定情况
issue 27732
是的。
这个代码是
只有
能够创建trait对象,但不能直接返回结构:
let mut b: Vec<Box<Boat>> = vec![];
populate(&mut b);
error[E0277]: the trait bound `Boat: std::marker::Unsize<Boat>` is not satisfied
--> src/main.rs:17:5
|
17 | populate(&mut b);
| ^^^^^^^^ the trait `std::marker::Unsize<Boat>` is not implemented for `Boat`
|
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<Boat>>` for `std::boxed::Box<Boat>`
note: required by `populate`
--> src/main.rs:25:5
|
25 | / fn populate<T: ?Sized>(receiver: &mut Vec<Box<T>>)
26 | | where
27 | | Box<Boat>: CoerceUnsized<Box<T>>,
28 | | {
29 | | receiver.push(Box::new(Boat) as Box<T>);
30 | | }
| |_____^
为了解决这个问题,您可以创建一个trait,就像我们对stable rust所做的那样,但是这个trait可以对所有trait对象都有一个全面的实现:
#![feature(unsize)]
use std::marker::Unsize;
trait Shipyard {
fn construct(boat: Boat) -> Box<Self>;
}
impl Shipyard for Boat {
fn construct(boat: Boat) -> Box<Self> {
Box::new(boat)
}
}
impl<U: ?Sized> Shipyard for U
where
Boat: Unsize<U>,
{
fn construct(boat: Boat) -> Box<Self> {
Box::new(boat) as Box<U>
}
}
fn populate<T: ?Sized>(receiver: &mut Vec<Box<T>>)
where
T: Shipyard,
{
receiver.push(T::construct(Boat));
}
多亏了
aturon for pointing me to these traits
和
to eddyb for reminding me that traits exist
啊!