admin管理员组文章数量:1430490
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
}
Playground link
So the reason I ended up here is I wanted a new function to be generic over SceneType
and have common functions that operate on any scene with
impl<T: SceneType> Scene<T> {
...
My problem is I can't box these types to store them in a vector because of the listed error messages. The error for 2 makes sense but I am trying to coerce it to a specific trait type as far as I am aware.
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
}
Playground link
So the reason I ended up here is I wanted a new function to be generic over SceneType
and have common functions that operate on any scene with
impl<T: SceneType> Scene<T> {
...
My problem is I can't box these types to store them in a vector because of the listed error messages. The error for 2 makes sense but I am trying to coerce it to a specific trait type as far as I am aware.
Share Improve this question edited Nov 19, 2024 at 16:20 kmdreko 62.1k6 gold badges95 silver badges164 bronze badges asked Nov 19, 2024 at 13:59 C. DowC. Dow 855 bronze badges1 Answer
Reset to default 6You are running afoul of the very limited Unsized Coercion rules.
Coercion from sized to unsized, such as here from struct to trait, only work in a few limited cases, of interest here:
- Type to trait, thus
SceneOne
todyn SceneType
. Foo<Type>
toFoo<Trait>
if:- The type implements the trait.
- The type parameter only appears once in the last field
Foo
. - The last field of
Foo
can itself be coerced to the appropriate unsized.
So for example, if I define:
struct Scene<ST: ?Sized>(ST);
// OR
struct Scene<ST: ?Sized>(Box<ST>);
Then the unsized coercion will work since all the points are ticked.
On the other hand, with your definition:
struct Scene<ST: ?Sized>(PhantomData<ST>);
Then the unsized coercion from Scene<T>
to Scene<U>
is only possible if PhantomData<T>: Unsize<PhantomData<U>>
(point 3), and that is not the case. You can see it's not listed in the implemented traits.
本文标签: rustWhy is this MyStructltTgt not coercing properly into MyStructltdyn TgtStack Overflow
版权声明:本文标题:rust - Why is this MyStruct<T> not coercing properly into MyStruct<dyn T>? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745556722a2663232.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论