使用枚举的场景通常是能够确定类型变动的范围,并且可以对此进行穷举
比如说角色的稀有类型有SS,S,A,B,C,这时角色的稀有度可以考虑将其设置为枚举类型
// 角色稀有度
enum RoleRarity {
SS,
S,
A,
B,
C,
}
里面每一个代表稀有度的项称为该枚举类型的一个变体
这个时候该类的对象可以这样声明
let ss_level = RoleRarity::SS;
let a_level = RoleRarity::A;
这里获取的便是枚举类中对应项的对象,就像抽卡一样,对象对应的就是那一项
接下来,由于枚举类型可以看成是我们自定义的一种数据类型,因此,我们可以将整个类型作为参数传给函数进行处理
// 根据角色稀有度播放抽卡动画
fn play_anim_by_rolerarity(role_rarity: RoleRarity) {
match role_rarity {
RoleRarity::SS => { println!("闪现彩色的光芒~"); }
RoleRarity::S => { println!("闪现金色的光芒~"); }
RoleRarity::A => { println!("廉价的特效~"); }
_ => { println!("特效都懒得给了~(-_-)~") }
}
}
此时的枚举只是区分了这几种变体,但是我们不知道变体怎么不同。就好比说一个人很厉害,拿别人不仅会问,怎么个厉害法?在这种场景下,枚举中的每一项可能需要一些信息来证明自己,接下来重新定义一下这个枚举类
// 角色稀有度
enum RoleRarity {
SS{
name: String,
live2D: bool,
bgm: String,
level: u32
},
S(String, String, u32),
A(String, u32),
B(String, u32),
C(u32),
}
枚举类在进行定义时,可以为其变体关联上对应的数据,相当于属性的概念,可以用于对于这个变体进行描述
相对应的,实例化过程也需要调整一下
let ss_level = RoleRarity::SS{
name: String::from("flying monster"),
live2D: true,
bgm: String::from(""),
level: 1
};
let a_level = RoleRarity::A(String::from("giant soilder"), 10);
接下来,为枚举类定义一个方法
impl RoleRarity {
fn playLive2D(&self) {
match self {
SS => { println!("开始播放~~"); }
_ => {}
}
}
}
这里同样是使用impl
块,相当于告诉你,这个块里的内容都是用作对应类的实现,相当于这个类的“工具箱”,这个方法的操作对象是这个类的实例,SS的卡会播放live2D,其他的类型就没这待遇了~
提及这个类型,就不得不说明一下空值相关的内容。
很多编程语言都存在一种情况的描述,当值不存在时,会用类似于null
的标识,这个概念就是空值,所表达的含义就是这个值因为某种原因不存在或者失效。那么,这就带来了一个变量的两种可能——null或者非null
在Rust中没有null这种类型,但是有这样的概念,标准库提供Option
这个枚举处理这样的情况
使用前还是先看下标准库的文档
pub enum Option<T> {
None,
Some(T),
}
差不多是这样的结构,如果是Some
对应的变体,那么就会包含非null的,对应的T的值,而如果返回的是None
变体,那么就为null,自然也就没有内容了。
let shoot1 = Option::Some(9);
let shoot2: Option<i32> = Option::None;
想象射击比赛,击中的环数表示成绩,但是也是有可能不幸脱靶,因此不是一定有环数,这就是一个可空的场景。如果只有击中环数的情况下,利用结果统计分数,那么所用到的就是非空值。
shoot1表示9环,编译器默认能够推导出T的类型为i32,shoot2则表示脱靶,用None代表这种场景,但是编译器不知道他的类型,那么我们必须指明
如果我们需要计算得分,是需要非空类型的
fn get_score(shoot: Option<i32>) {
match shoot {
Option::Some(value) => {
println!("成绩=>{}", value * 5);
}
Option::None => {
println!("脱靶了,老哥~");
}
}
}
使用match对于类型进行判断,Some
变体可以直接获取包裹的对应类型的非空值,从而传递给对应的处理逻辑