0

Assuming the following Rust code:

trait  MyTrait {...}
struct MyStruct;
impl   MyTrait for MyStruct {...}
impl   MyStruct {
     pub fn new() -> MyStruct { MyStruct{...} }
}

I'm able to write:

let foo: MyStruct = MyStruct::new();

However I can't

let bar: MyTrait  = MyStruct::new();

Other interface-oriented programming languages can do that. Am I missing something? How can I pass various objects to a method that accepts only MyTrait? Do I need to use "templates" such as my_method<T: MyTrait>(param: T) {...}?

petrbel
  • 2,428
  • 5
  • 29
  • 49

2 Answers2

1

You don't need to define bar as a MyTrait object. (This is even the wrong thinking, because rust doesn't really have inheritance. Think of traits as more like interfaces in Java. In this case, it seems like you're treating MyTrait as a superclass of MyStruct)

You can do this

let bar = MyStruct::new();

and then just pass it in function defined like this:

fn my_method<T: MyTrait>(param: T) {...}

my_method(bar)

This works because Rust statically checks that bar, which is of type MyStruct, implements the trait MyTrait.

Side note: If you want to create a vector of trait objects, check this question.

Community
  • 1
  • 1
Jacob Wang
  • 4,411
  • 5
  • 29
  • 43
  • I think of traits as interfaces in Java, therefore I expect `MyInterface i = new MyClass();` be working. Anyway, thanks for help, I'll do it as you proposed. – petrbel Aug 29 '15 at 10:11
  • 1
    @petrbel: that would be equivalent to `let bar: Box = Box::new(MyStruct::new());`. – Chris Morgan Aug 29 '15 at 12:48
1

This is because a trait may be implmented by many types and therefor the size of bar is unknown. However a reference's size would be know, so the following works.

trait MyTrait {}
struct MyStruct;
impl MyTrait for MyStruct {}
impl MyStruct {
    fn new() -> Self {
        MyStruct
    }
}

fn main() {
    let foo: MyStruct = MyStruct::new();
    let bar: &MyTrait = &MyStruct::new();
}

Notice that bar isn't a MyTrait, it's a &MyTrait, this is called a trait object.

Nathan Lilienthal
  • 864
  • 1
  • 10
  • 16