Reputation: 31
For a larger Programm, I've tried to introduce a new trait to pass some different enums through a function.
We got this situation:
enum One { One, Two}
enum Two {Three, Four}
I used a trait like this:
pub trait NewTrait {}
Then:
impl NewTrait for One {}
impl NewTrait for Two {}
then we have a function:
fn foo<T: NewTrait> (test: T) {
match test{
One::One => println!("One"),
One::Two => println!("Two"),
Two::Three => println!("Three"),
Two::Four => println!("Four"),
}
}
We use:
fn main() {
foo(One::One);
foo(Two::Three);
}
Then I got this errormessage:
Compiling Examplecode v0.1.0 (/Users/maximilianwittich/projects/Examplecode)
error[E0308]: mismatched types
--> src/main.rs:18:9
|
9 | enum One { One, Two}
| --- unit variant defined here
...
16 | fn foo<T: NewTrait>(test: T) {
| - this type parameter
17 | match test{
| ---- this expression has type `T`
18 | One::One => println!("One!"),
| ^^^^^^^^ expected type parameter `T`, found enum `One`
|
= note: expected type parameter `T`
found enum `One`
error[E0308]: mismatched types
--> src/main.rs:19:9
|
9 | enum One { One, Two}
| --- unit variant defined here
...
16 | fn foo<T: NewTrait>(test: T) {
| - this type parameter
17 | match test{
| ---- this expression has type `T`
18 | One::One => println!("One!"),
19 | One::Two => println!("Two!"),
| ^^^^^^^^ expected type parameter `T`, found enum `One`
|
= note: expected type parameter `T`
found enum `One`
error[E0308]: mismatched types
--> src/main.rs:20:9
|
10 | enum Two {Three, Four}
| ----- unit variant defined here
...
16 | fn foo<T: NewTrait>(test: T) {
| - this type parameter
17 | match test{
| ---- this expression has type `T`
...
20 | Two::Three => println!("Three!"),
| ^^^^^^^^^^ expected type parameter `T`, found enum `Two`
|
= note: expected type parameter `T`
found enum `Two`
error[E0308]: mismatched types
--> src/main.rs:21:9
|
10 | enum Two {Three, Four}
| ---- unit variant defined here
...
16 | fn foo<T: NewTrait>(test: T) {
| - this type parameter
17 | match test{
| ---- this expression has type `T`
...
21 | Two::Four => println!("Four!")
| ^^^^^^^^^ expected type parameter `T`, found enum `Two`
|
= note: expected type parameter `T`
found enum `Two`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.
error: could not compile `Examplecode`
Can anybody explain to me what's going on? Maybe with a bit brighter explanation, since I honestly try to learn to code in Rust.
Upvotes: 1
Views: 1485
Reputation: 154886
I do not understand in particular what type of action I try to perform here? In other words, what should the trait provide to use the match switch?
Instead of attempting to match across all possibilities (which is impossible, as any number of types could implement the trait), your trait should provide the behavior you need in foo
. For example:
// enum One and Two defined as in the question
pub trait NewTrait {
fn display(&self);
}
impl NewTrait for One {
fn display(&self) {
match self {
One::One => println!("One"),
One::Two => println!("Two"),
}
}
}
impl NewTrait for Two {
fn display(&self) {
match self {
Two::Three => println!("Three"),
Two::Four => println!("Four"),
}
}
}
fn foo<T: NewTrait>(test: T) {
test.display();
}
If you really insisted on matching all options, the trait could provide that as well, e.g. using a custom enum that squashes the existing enums:
// enum One and Two defined as in the question
enum Match {
One,
Two,
Three,
Four,
}
trait NewTrait {
fn as_match(&self) -> Match;
}
impl NewTrait for One {
fn as_match(&self) -> Match {
match self {
One::One => Match::One,
One::Two => Match::Two,
}
}
}
impl NewTrait for Two {
fn as_match(&self) -> Match {
match self {
Two::Three => Match::Three,
Two::Four => Match::Four,
}
}
}
fn foo<T: NewTrait>(test: T) {
match test.as_match() {
Match::One => println!("One"),
Match::Two => println!("Two"),
Match::Three => println!("Three"),
Match::Four => println!("Four"),
}
}
It's hard to tell whether this makes any sense because we don't know the actual problem you're trying to solve. But hopefully it gives you an idea of what you can accomplish with traits and generics.
See also the chapter on traits in the book.
Upvotes: 1