use std::marker::PhantomData;
trait SceneType {}
struct Scene<SceneType: ?Sized> {
_phantom: PhantomData<SceneType>
}
pub enum SceneOne {}
impl SceneType for SceneOne {}
impl<SceneOne> Scene<SceneOne> {
pub fn new() -> Self {
Self {
_phantom: Default::default()
}
}
}
fn main() {
let scene = Scene::<SceneOne>::new();
//works fine
//1 let boxed_scene: Box<Scene<dyn SceneType>> = Box::new(Scene::<SceneOne>::new());
// expected `Scene<dyn SceneType>`, found `Scene<SceneOne>` ... you could box the found value and coerce it to the trait object `Box<dyn SceneType>
//2 let boxed_scene: Box<Scene<dyn SceneType>> = Box::new(scene) as Box<Scene<dyn SceneType>>;
// as` expression can only be used to convert between primitive types or to coerce to a specific trait object
}
所以我最终来到这里的原因是我想要一个新函数在 SceneType 上通用,并且具有可在任何场景上运行的通用函数
impl<T: SceneType> Scene<T> {
...
我的问题是,由于列出的错误消息,我无法将这些类型装箱以将它们存储在向量中。 2 的错误是有道理的,但据我所知,我试图将其强制为特定的特征类型。
感谢您的帮助!
游乐场链接
您违反了非常有限的Unsized Coercion规则。
从大小到未大小的强制转换,例如这里从结构到特征,仅在少数有限的情况下起作用,这里感兴趣:
SceneOne
为 dyn SceneType
。Foo<Type>
至 Foo<Trait>
如果:
Foo
。Foo
的最后一个字段本身可以被强制为适当的未调整大小。例如,如果我定义:
struct Scene<ST: ?Sized>(ST);
// OR
struct Scene<ST: ?Sized>(Box<ST>);
然后,由于所有点都已勾选,因此未调整大小的强制转换将起作用。
另一方面,按照你的定义:
struct Scene<ST: ?Sized>(PhantomData<ST>);
那么,从
Scene<T>
到 Scene<U>
的无大小强制转换只有在 PhantomData<T>: Unsize<PhantomData<U>>
(第 3 点)的情况下才可能实现,但事实并非如此。您可以在已实现的特征中看到它没有列出。