3

I have a trait object, and I want to know the concrete object that it points to, but I cannot work out how to get the concrete object.

What I want is something like the following:

trait MyClonable {
   /** copy from another MyClonable */
   fn my_clone_from(&mut self, other: &Self)->Result<(), MyError>;
}

impl MyClonable for SomeType {
   fn my_clone_from(&mut self, other: &MyClonable)->Result<(), MyError> {...}
}

So that I can say something like:

let mut new_thing = SomeType::new();
new_thing.my_clone_from(&old_thing)?;

Then the new_thing will contain a sort-of copy of the old_thing, unless old_thing is of an unexpected type, in which case it should return an error.

But Rust will not let me get something like an Option<&SomeType> from a MyClonable.

sshashank124
  • 31,495
  • 9
  • 67
  • 76
Martin Ellison
  • 1,043
  • 1
  • 13
  • 25

1 Answers1

1

You cannot. The trait object only gives you access to the trait methods. You would need to manually specify which concrete type to downcast to as described in this QA: How to get a reference to a concrete type from a trait object?.

Then, you could try downcasting to each of your known types until one of them succeeds but that is dirty.

Instead, using generics would be a better fit:

trait MyClonable<T> {
    fn my_clone_from(&mut self, other: &T);
}

And now you can implement this trait for all your supported types:

impl MyClonable<u32> for i32 {
    fn my_clone_from(&mut self, _other: &u32) { }
}

impl MyClonable<Tomato> for i32 {
    fn my_clone_from(&mut self, _other: &Tomato) { }
}
sshashank124
  • 31,495
  • 9
  • 67
  • 76