pub enum Value {
Int8(i8),
Int16(i16),
Int32(i32),
}
match value {
// in 2024-02-23 rust nightly version is error
Value::Int8(v) | Value::Int16(v) | Value::Int32(v) => { do_something() }
}
but i think here the compiler can cast all value to i32. Does here any features or plan?
No, you can't match different types using the same match variable like that. You're going to have to write three separate match arms.
However, depending on the structure of your code, you might be able to write a From or TryFrom impl, or at least a conversion method, so that you only need to write that match once.
Allow "local" bindings in complex expressions with patterns (first of all, match)
Add optional "in let" (or alternatively "where let") clause after MatchArmGuard for new binding
If we allow these 2 features, we could write next:
pub enum Value {
Int8(i8),
Int16(i16),
Int32(i32),
}
match value {
Value::Int8(local v1) in let v = i32::from(v1)
| Value::Int16(local v2) in let v = i32::from(v2)
| Value::Int32(v)
=> { do_something() }
}
But is it unclear how is it appropriate for the rust community and how is this difficult to add into the language.
match value {
Value::Int8(local v1) in let v = i32::from(v1)
| Value::Int16(local v2) in let v = i32::from(v2)
| Value::Int32(v)
=> { do_something(v) }
}
It would be tedious to have to write that match expression in a bunch of places... which is where @josh's suggestions come in. Concretely, this compiles now:
fn do_something(x: i32) { println!("got here: {x}"); }
pub enum Value {
Int8(i8),
Int16(i16),
Int32(i32),
}
// explicit conversion with callback -- may be needed for
// more complicated inner structures
impl Value {
pub fn apply<T, F: FnOnce(i32) -> T>(&self, f: F) -> T {
match *self {
Value::Int8(v) => f(v.into()),
Value::Int16(v) => f(v.into()),
Value::Int32(v) => f(v.into()),
}
}
}
// enable into() -- better for anything that's Copy
impl std::convert::From<Value> for i32 {
fn from(v: Value) -> i32 {
match v {
Value::Int8(v) => v.into(),
Value::Int16(v) => v.into(),
Value::Int32(v) => v.into(),
}
}
}
pub fn do_something_with_value_1(v: Value) {
v.apply(do_something)
}
pub fn do_something_with_value_2(v: Value) {
do_something(v.into())
}