Reputation: 7809
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
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