regarding my last thread I decided to stop and refactor my code. My approach now is to downcast the trait object. Never did this before.
This time there is no gist because downcast is not available on playground.
toml
[package]
name = "k"
version = "0.1.0"
authors = ["xxx"]
edition = "2018"
[dependencies]
downcast = "*"
error:
error[E0599]: no method named `downcast_ref` found for type `std::boxed::Box<(dyn Component + std::marker::Send + 'static)>` in the current scope
--> src/main.rs:30:16
|
30 | (*component).downcast_ref::<XComponent>().unwrap().machine.as_ref().unwrap()
| ^^^^^^^^^^^^ method not found in `std::boxed::Box<(dyn Component + std::marker::Send + 'static)>`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `downcast_ref`, perhaps you need to implement it:
candidate #1: `downcast::Downcast`
What is the problem here? Is it the "Send + 'static"?
The note in the error message tells you what you need to do:
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `downcast_ref`, perhaps you need to implement it:
candidate #1: `downcast::Downcast`
You can't use methods from the Downcast trait unless that trait is in scope. Add use downcast::Downcast to your file.
Ah, you might have been correct that your + Send + 'static bounds are the issue, then. I'm not familiar enough with downcast to suggest how to fix that part
This example shows that downcast! macro receives the trait itself and not the trait object. What if you replace downcast!(dyn Component) with downcast!(Component)?
Could anyone help me getting this downcast to work? I switched to downcast_rs but get another problem.
#[macro_use]
extern crate downcast_rs;
use std::any::Any;
use downcast_rs::DowncastSync;
pub trait Component: DowncastSync {
fn get_name(&self) -> String;
}
impl_downcast!(sync Component);
#[derive(Clone)]
struct X;
#[derive(Clone)]
pub struct XComponent {
machine: Option<X>,
}
impl Component for XComponent {
fn get_name(&self) -> String {
"X".into()
}
}
fn main()
{
let x = Box::new(XComponent{machine: Some(X{})});
let state0 = get_state(&x);
}
fn get_state<'a>(component: &Box<dyn Component + Send + 'static>) -> X
{
let x = component.clone();
let x: Result<Box<XComponent>, _> = (*x).downcast();
x.ok().unwrap().machine.unwrap()
}
2 errors
error[E0308]: mismatched types
--> src/main.rs:29:28
|
29 | let state0 = get_state(&x);
| ^^ expected trait Component, found struct `XComponent`
|
= note: expected type `&std::boxed::Box<(dyn Component + std::marker::Send + 'static)>`
found type `&std::boxed::Box<XComponent>`
error[E0599]: no method named `downcast` found for type `std::boxed::Box<dyn Component + std::marker::Send>` in the current scope
--> src/main.rs:35:43
|
35 | let x: Result<Box<XComponent>, _> = (*x).downcast();
| ^^^^^^^^ method not found in `std::boxed::Box<dyn Component + std::marker::Send>`