Recently I've been working on learning advanced Rust. As part of that, I'm learning to use dynamic dispatch.
In my tinkering I've run across a bit of an issue. For some reason, I can't seem to access fields of structs which have been assigned to variables using Boxes and dynamic dispatch. For example,
fn main() {
let z: Box<dyn S>;
z = Box::new(A::new());
println!("{}", z.val);
}
trait S {
fn new () -> Self where Self: Sized;
}
struct A {
val: i32,
}
impl S for A {
fn new () -> A {
A {val: 1}
}
}
struct B {
val: i32
}
impl S for B {
fn new() -> B {
B {val:2}
}
}
yields the error message "error[E0609]: no field val on type Box<dyn S>"
Is there any way to access such fields, or do I need to kluge together a workaround?
It is easy to understand why this does not work if you understand what a trait object is. When a method returns a dyn Trait it does not return an instance of any struct. Instead it returns a lookup table, which tells the caller where to find its methods. So the caller can access methods without knowing anything about underlying struct itself.
So if the caller does not have access to the struct itself it's clear it cannot access its fields.
There are two ways to implement what you are trying to do:
enum. If you know complete list of options that the method can return, it's the best and the most Rust'y solution.enum S {
A { val: i32, anotherAval: u32 },
B { val: i32, anotherBval: f32 },
}
impl S {
fn val(&self) -> i32 {
match self {
S::A => A.val,
S::B => B.val,
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With