How do I return an instance of a trait from a method?

Rust 1.26 and up

impl Trait now exists:

fn create_shader(&self) -> impl Shader {
    let shader = MyShader;
    shader
}

It does have limitations, such as not being able to be used in a trait method and it cannot be used when the concrete return type is conditional. In those cases, you need to use the trait object answer below.

Rust 1.0 and up

You need to return a trait object of some kind, such as &T or Box<T>, and you're right that &T is impossible in this instance:

fn create_shader(&self) -> Box<Shader> {
    let shader = MyShader;
    Box::new(shader)
}

See also:

  • What is the correct way to return an Iterator (or any other trait)?
  • Conditionally iterate over one of several possible iterators

I think this is what you were searching for; a simple factory implemented in Rust:

pub trait Command {
    fn execute(&self) -> String;
}

struct AddCmd;
struct DeleteCmd;

impl Command for AddCmd {
    fn execute(&self) -> String {
        "It add".into()
    }
}

impl Command for DeleteCmd {
    fn execute(&self) -> String {
        "It delete".into()
    }
}

fn command(s: &str) -> Option<Box<Command + 'static>> {
    match s {
        "add" => Some(Box::new(AddCmd)),
        "delete" => Some(Box::new(DeleteCmd)),
        _ => None,
    }
}

fn main() {
    let a = command("add").unwrap();
    let d = command("delete").unwrap();
    println!("{}", a.execute());
    println!("{}", d.execute());
}

Tags:

Traits

Rust