It seems as though you can't. If not, is there any planned support to add it or run-time type information (RTTI)?
struct Bus;
struct Car;
struct Person;
fn main() {
let x = Bus;
//or more realistically, let x = function_with_multiple_return_types();
match x {
Car => {
// ...
}
Bus => {
// this gets executed
}
Person => {
// ...
}
}
}
This example is trivial. In real life, it would only be useful if x
could be multiple types. e.g. let x = function_with_multiple_return_types();
.
No one can say with 100% accuracy that a feature will or won't ever be implemented, but I can say with 100% belief that this will never be implemented.
Why is that? Because there's zero benefit to the proposed syntax. Rust is a statically-typed language. That means that the compiler knows what the type of a variable is. There's no way that any branch besides Bus
would ever be executed. There's no way that a variable can have more than one type! Why would the language change to allow you to add code that could never be used? That wouldn't be very useful.
A match statement, and pattern matching in general, is really only useful when there are multiple possible variants of something. That's why Rust has enum
s; to allow a fixed set of dynamic choices (a.k.a. made at runtime).
If you need an open set of dynamic decisions, that's what traits (and maybe specialization) are for. There's even a trait that allows for any concrete type.
As mentioned in the comments, you can use trait object downcasting which is provided by Any
, but there's no ability to use match
.
See also:
Check out std::any::Any
and Andrew Johnson's link. I think you will be able to do something close to what you wanted to do using Any
. fn get_type_id(&self) -> TypeId
is only in the nightly builds though, so if you have the stable version of Rust you may be unable to use it yet.
This example is close to what you want, just with if let
instead of match
.
I wrote three examples to demonstrate how you might accomplish this, Although none are usable with match
sadly... They can be found be found and run here. The following is my favorite way of doing it:
fn run_example_one() {
let unknown_type = gen_rand_any();
if let Some(string) = unknown_type.downcast_ref::<String>() {
println!("It's a string!");
} else if let Some(my_struct) = unknown_type.downcast_ref::<MyStruct>() {
println!("my struct! name = {:?}", my_struct.my_name);
} else if let Some(int) = unknown_type.downcast_ref::<i32>() {
println!("something singed 32 bit int.");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With