enums - valor - recorrer enum c#
En Rust, ¿hay una manera de iterar a través de los valores de una enumeración? (3)
Vengo de un fondo de Java y podría tener algo como enum Direction { NORTH, SOUTH, EAST, WEST}
y podría hacer algo con cada uno de los valores a su vez con el bucle mejorado para:
for(Direction dir : Direction.values()) {
//do something with dir
}
Me gustaría hacer algo similar con los enums de Rust.
Implementé funcionalidad básica en la caja plain_enum
.
Se puede usar para declarar una enumeración de tipo C de la siguiente manera:
#[macro_use]
extern crate plain_enum;
plain_enum_mod!(module_for_enum, EnumName {
EnumVal1,
EnumVal2,
EnumVal3,
});
Y luego le permitirá hacer cosas como las siguientes:
for value in EnumName::values() {
// do things with value
}
let enummap = EnumName::map_from_fn(|value| {
convert_enum_value_to_mapped_value(value)
})
No, no hay ninguno. Creo que eso se debe a que los enums en Rust son mucho más poderosos que en Java; de hecho, son tipos de datos algebraicos completos. Por ejemplo, cómo esperaría iterar sobre los valores de esta enumeración:
enum Option<T> {
None,
Some(T)
}
?
Su segundo miembro, Some
, no es una constante estática, la usa para crear valores de la Option<T>
:
let x = Some(1);
let y = Some("abc");
Por lo tanto, no hay una forma sensata de iterar sobre los valores de cualquier enumeración.
Por supuesto, creo que sería posible agregar soporte especial para enums estáticos (es decir, enums con solo elementos estáticos) en el compilador, por lo que generaría alguna función que devuelva los valores de la enumeración o un vector estático con ellos, pero cree que la complejidad adicional en el compilador simplemente no vale la pena.
Si realmente desea esta funcionalidad, puede escribir una extensión de sintaxis personalizada (consulte this problema). Esta extensión debe recibir una lista de identificadores y generar una enumeración y un vector constante estático con estos identificadores como contenido. Una macro regular también funcionaría en cierta medida, pero hasta donde recuerdo no se pueden transcribir argumentos de macro con multiplicidad dos veces, por lo que tendrá que escribir los elementos de enumeración dos veces manualmente, lo que no es conveniente.
También este tema puede ser de interés: # 5417
Y, por supuesto, siempre puede escribir código que devuelve una lista de elementos de enumeración a mano.
Si la enumeración es similar a C (como en tu ejemplo), entonces puedes hacer esto:
use self::Direction::*;
use std::slice::Iter;
#[derive(Debug)]
pub enum Direction { North, South, East, West }
impl Direction {
pub fn iterator() -> Iter<''static, Direction> {
static DIRECTIONS: [Direction; 4] = [North, South, East, West];
DIRECTIONS.into_iter()
}
}
fn main() {
for dir in Direction::iterator() {
println!("{:?}", dir);
}
}