整数与枚举
在 Rust 中,从枚举到整数的转换很容易,但是反过来,就没那么容易,甚至部分实现还挺不安全, 例如使用 transmute。
在实际场景中,从整数到枚举的转换有时还是非常需要的,例如为了可读性,有一个枚举类型,然后需要从外面传入一个整数,用于控制后续的流程走向,此时就需要用整数去匹配相应的枚举。
手动匹配
为了实现这个需求,不要求数字转换枚举,可以利用枚举容易转换数字的特性进行匹配:
1 | enum Status { |
使用三方库
在手动匹配中,是没有实现数字转换枚举流程的,可以使用第三方库 num-traits
和 num-derive
来实现这个过程:
1 | use num_derive::FromPrimitive; |
使用第三方库后,可以无需手动转换,使用 Optional 即可完成匹配。另外还可以使用一个较新的库: num_enums:
1 | use num_enum::{IntoPrimitive, TryFromPrimitive}; |
TryFrom 特征
如果不希望使用第三方库,自己也可以使用 TryFrom 实现转换逻辑。
1 | // 使用TryFrom实现转换逻辑,将给定的数据结合给定的类型,使用TryFrom特征定义的逻辑进行转换 |
为枚举实现 TryFrom 特征,i32 使用 try_into 方法,try_into 调用的是目标类型的 TryFrom 特征逻辑,再一次应证了 rust 强大的类型系统,它可以使用上下文信息,以进行转换。
标注合适的类型 + try_into 方法 = 类型自由
上面还有一个问题,需要为每个类型都定义一遍匹配分支,可以使用宏来解决这个问题:https://course.rs/advance/into-types/enum-int.html#tryfrom--%E5%AE%8F
std::mem::transmute
这个方法原则上并不推荐,但是有其存在的意义,如果要使用,需要清晰的知道自己为什么使用,这属于 unsafe 代码。
总结
枚举非常容易转化成数字,但是数字不容易转换成枚举。可以利用枚举容易转化成数字特性来实现枚举与数字的匹配。
Code
1 | fn main() { |