Is there any type or crate maybe that provides the ability to use dyn Any
for a type that has a lifetime parameter? I have to be able to store a vector of trait objects ( Vec<Box<dyn DynamicBorrow<'a> + 'a>> ), but I need to be able to downcast the borrow to its concrete type which is either DynamicView<'a, T>
or DynamicViewMut<'a, T>
.
You don’t provide much detail about the types in question here. If you know that your DynamicBorrow
is either DynamicView
or DynamicViewMut
, you could consider an enum over a trait. As long as T
is static, you could perhaps work with something like
enum DynamicBorrow<'a> {
View(DynamicView<'a, dyn Any>),
ViewMut(DynamicViewMut<'a, dyn Any>),
}
Then perhaps working with Vec<DynamicBorrow<'a>>
is enough. You would even save the Box
.
Whether the above code makes sense or not of course depends heavily on how DynamicView
and DynamicViewMut
actually are defined, in particular if T
can be unsized. If not, then perhaps a DynamicView<'a, Box<dyn Any>>
(and similarly for the second enum variant) could make sense.
Yeah, wait a second, I think the enum might work. I was thinking it wouldn't for some reason earlier, but now that I think about that again I think that will be fine. I'll try it and come back if it doesn't work ( and provide some more details ). Thanks.
So T
in my use-case cannot be unsized and is T: 'static + Send + Sync
. In fact the current plan is that it will always be an array of bytes, but possibly with a different length. For example: [u8; 16]
, [u8; 32]
, [u8; 64]
, etc. and it needs to be stack allocated for performance reasons ( thus an array and not a vector. DynamicView
is defined as :
pub struct DynamicView<'a, T> {
pub view: Option<View<'a, T>>,
pub storage_id: StorageId,
}
Where View
is:
pub struct View<'a, T> {
window: Window<'a, T>,
_borrow: Borrow<'a>,
_all_borrow: Borrow<'a>,
}
In your example with the enum:
enum DynamicBorrow<'a> {
View(DynamicView<'a, dyn Any>),
ViewMut(DynamicViewMut<'a, dyn Any>),
}
Will I be able to do something like:
match my_dynamic_borrow {
DynamicBorrow::View(view) => {
// I will know the length of the length because of dynamically obtained data
// and the goal is to downcast it something like this
if length == 16 {
let view = view as DynamicView<[u8; 16]>;
// Do stuff with view
} else if length == 32 {
let view = view as DynamicView<[u8; 32]>;
// Do stuff with view
}
// etc.
}
// And the smae for DynamicBorrowMut
}
Is Window
a type of yours, too, or does it come from another crate? I would be interested in the whole hierarchy where the parameter T
goes. If T
cannot be unsized, like you said, then, like I said above, the enum would probably have to look more like
enum DynamicBorrow<'a> {
View(DynamicView<'a, Box<dyn Any>>),
ViewMut(DynamicViewMut<'a, Box<dyn Any>>),
}
Oh, OK. So I'm trying to build a scripting system for the shipyard
ECS. Things got a little bit hairy with the the type system in ways that I thought were going to be a bit simpler. I'll try to articulate this a bit better and get the real code public and cover the broader topic a bit better as soon as I get the chance.
I'll include the maintainer, too.
I can’t really think of a nice safe approach here, honestly. Maybe a lack of creativity. Using some unsafe code, one could imagine this approach to be reasonable. I personally am not going to guarantee that this kind of interface is actually sound, but I hope it is.
Wow, thanks for the example. I'll definitely take a look at it.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.