Rust: downcasting and Box <Any>

pub struct WidgetWrap { // ... widget: RefCell<Box<Any>>, } 

At some point, I want to drop Box<Any> into Box<WidgetTrait>

 let mut cell = widget.borrow_mut(); let w = cell.downcast_mut::<Box<WidgetTrait>>(); 

This gives me an error of this kind:

 error: instantiating a type parameter with an incompatible type `Box<WidgetTrait>`, which does not fulfill `'static` [E0144] 

What does it mean?

I looked at How to fix it: the value may contain links; add `static` attached to` T` and tried to add + 'static everywhere.

 pub struct WidgetWrap { // ... widget: RefCell<Box<Any + 'static>>, } let mut cell = widget.borrow_mut(); let w = cell.downcast_mut::<Box<WidgetTrait + 'static>>(); 

It fixes compilation errors, but fails when I try to maximize a fallen window, as shown above. And yes, the contents of the field is an object that implements WidgetTrait .

Obviously, I am coding in Rust at a level that I don't quite understand. But maybe someone will help me better understand the concepts involved in the above task.

+5
source share
1 answer

(I will ignore the 'static part as its comparatively inconsequential for the Im parts explaining.)

Box<Trait> for this Trait attribute is stored as two pieces of data: a pointer to the actual data in memory and a pointer to vtable to implement its Trait types.

From this you can see that you have only one level of traityness - if you have a Box<WidgetTrait> and you set it again as a Box<Any> , you can only get it as a Box<WidgetTrait> object. Similarly, if you take a Widget type that implements WidgetTrait and puts it in a Box<Any> , you can only get it as a Widget object, not as a Box<WidgetTrait> object.

This is the nature of type identifiers that are used domestically: unlike a dynamic or virtual language, a type system is a pure compilation time construct; at run time there is no such system as type.

The solution, if you really need a solution on these lines (you probably shouldn't: stick with just Box<WidgetTrait> , probably the best way) is to have a trait that also implements what Any does. This is currently not the easiest thing, but it can be done. Teepees Header trait - an example of how this can work; a Box<Header> object will have header conversion methods, as well as Any s .downcast_ref() , etc.

+9
source

Source: https://habr.com/ru/post/1200032/


All Articles