Looking for an Equivalent of Java/C# "Object" Type or C/C++ "void *" Type


#1

I require a trait of the following form:

trait Foo {
    fn bar(&self) -> Object;
}

In summary: I have a trait with a method that must return different types depending on the implementation.

In Java or C# I could implement such a method by using a return type of “Object”. In C or C++ I could do the same by returning a “void *”.

What is the appropriate way to handle this situation in Rust?


#2

In rust you use generics wherever you can. In your case, you probably want an associated type:

trait Foo {
    type Object;
    fn bar(&self) -> Self::Object;
}
impl Foo for i32 {
    type Object = i64;
    fn bar(&self) -> i64 { *self as i64 }
}
fn main() {
    let x: &Foo<Object=i64> = &5i32;
    let y: i64 = x.bar();
}

every implementor of Foo can have his own return type for bar. When you erase the type and only have a &Foo, you need to specify the Object type, otherwise Rust cannot allow you to call the bar function as it won’t know how much memory to allocate and what type it is.

EDIT: @phaylon is correct, without knowing your use case, your question has many answers. The most similar to Java’s Object and c’s void* is Any. But Any should only be used if all other avenues have been explored.


#3

Can you give more information about your actual use-case? Because there are multiple strategies available, depending on what you want to achieve:

  • If you have a fixed, non-extendable set of possible types that can be returned, I’d use an enum Object.
  • If you want to enforce that the returned type implements certain behaviors, a trait object should work.
  • If you want the implementor of the trait to declare a fixed type that it will return, you can use associated types.
  • If you want to go full dynamic with regards to the type, there is also Any. Though I haven’t used this yet, and I would try one of the above strategies first.

#4

Thank you for your replies. Your responses answered my question.

Here is some background:

I’m building a library which will allow you write an XML specification for items (LEDs, Servos, Motors, etc.) plugged into a microcontrollers and then generate rust classes which can be used to control the devices across a network.

I wrote a similar library with C# and used it to control networks of ~16 microcontrollers for 3 different projects but it requires that the microcontrollers work with a C# runtime like Mono. This is why I am rewriting the library in Rust.

I agree that it is much safer to use generic types rather than mess with dynamics. However, during the development of the C# version of this code I found that it was useful to have dynamic types for things that I wasn’t finished implementing. Essentially, this allowed me to easily test some portions of the code during development which were partially incomplete. I plan to use a similar development strategy for the Rust version of this software which is why I was curious if there was an equivalent.

Thank you guys for your help!