Reputation: 6042
Is there a position for @ operator or some other solution that would bind the variable in a match arm to a variant type rather than to the entire enum? In the following example, all bar
, baz
and qux
have types of Foo, rather than Foo::Bar, Foo::Baz, Foo::Qux and the sample fails to compile.
enum Foo {
Bar(i32),
Baz{s: String},
Qux,
}
fn main() {
let foo = Foo::Bar(42);
match foo {
bar @ Bar(..) => bar.0.to_string(),
baz @ Baz{..} => baz.s,
qux @ Qux => "".to_owned(),
}
}
Upvotes: 11
Views: 20721
Reputation: 26697
To reuse a variant enum you need to use enum tuple style and define external structure, it's a lot more used than enum struct:
struct Bar(i32);
struct Baz {
s: String,
}
enum Foo {
Bar(Bar),
Baz(Baz),
Qux,
}
fn main() {
let foo = Foo::Bar(Bar(42));
let foo = match foo {
Foo::Bar(bar) => bar.0.to_string(),
Foo::Baz(baz) => baz.s,
Foo::Qux => "".to_owned(),
};
assert_eq!(foo, "42");
}
Upvotes: 5
Reputation: 997
Though handy if they existed, there is no such thing as an enum variant type in Rust. All variants have the same type. Their contents, on the other hand, might carry values of different types.
For example, both Foo::Bar(1)
and Foo::Qux
have the same type, which is Foo
. So you can't bind those values and treat them differently as they are of the same type.
The most “idiomatic” solution I can think of is to just grab what's inside of the specific enum variant you're currently matching on, like so:
fn main() {
let foo = Foo::Bar(42);
let my_string = match foo {
Bar(bar) => bar.to_string(),
Baz{ s } => s,
Qux => "".to_owned(),
};
}
Upvotes: 1
Reputation: 2182
What you're looking for is use
:
enum Foo {
Bar(i32),
Baz{s: String},
Qux,
}
fn main() {
use Foo::*;
let foo = Bar(42);
let s = match foo {
Bar(bar) => bar.to_string(),
Baz{s} => s,
Qux => "".to_owned(),
};
}
Upvotes: 0
Reputation: 1455
I think the syntax you're looking for is this?
enum Foo {
Bar(i32),
Baz{s: String},
Qux,
}
fn main() {
let foo = Foo::Bar(42);
let s = match foo {
Foo::Bar(bar) => bar.to_string(),
Foo::Baz{s} => s,
Foo::Qux => "".to_owned(),
};
dbg!(s);
}
Upvotes: 1