Denis Steinman
Denis Steinman

Reputation: 7809

How deduce a generic type of variable?

I declared Lexer trait:

trait Lexer<T> {}

Also I've implemented it for two structures:

impl Lexer<A> for ContainerA {}

impl Lexer<B> for ContainerB {}

Now I am trying to declare variable via ternary operator:

let lexer: Lexer<?> = if args.mode == 0 { ContainerA::new() } else { ContainerB::new() };

Of course, this code is wrong but... How to write correctly? To rust deduce a generic type basing on condition. Is it possible?

In short, there isn't any difference about variable type for me, I just need a some implementation of Lexer to use its methods.

Upvotes: 0

Views: 312

Answers (1)

Sunreef
Sunreef

Reputation: 4552

You can create a trait object by wrapping it in a Box so that its size is known at compile-time.

trait Lexer {
    fn lex(&self);
}

struct ContainerA;
struct ContainerB;

impl Lexer for ContainerA {
    fn lex(&self) {
        println!("A");
    }
}

impl Lexer for ContainerB {
    fn lex(&self) {
        println!("B");
    }
}

Depending on your condition, you can assign different trait objects to your lexer.

let value = 0;
let lexer: Box<Lexer> = if value == 0 {
    Box::new(ContainerA)
} else {
    Box::new(ContainerB)
};
lexer.lex();

If you know all the types that implement your trait, you can also use an enum type.

enum Container {
    A(ContainerA),
    B(ContainerB),
}

Based on your condition, you can use either value of the enum while having a fixed type for your variable:

let lexer: Container = if args.mode == 0 { 
    Container::A(ContainerA::new())
} else {
    Container::B(ContainerB::new())
};

Upvotes: 1

Related Questions