0. 枚举模式
在rust中,枚举通常表达了特定的语义,深刻的嵌入到rust语言中,作为语言密不可分的一部分。对于这些枚举,我把他归结出来作为rust的枚举模式。
什么事枚举模式?它有如下特征
- 特征一、枚举表达语义,语义是第一位的,例如Option的两个枚举值,一个代表控制,一个代表可能值
- 特征二、枚举是泛型的,有1个多个泛型值定义
- 特征三、泛型值可能有约束,例如说Cow,意味着只有实现了约束的值才能实现Cow
- 特征四、有自定义的函数,例如impl<T> Option<T> {}
- 特征五、关键库中作为函数的返回值
按照这些特征我们来学习几个和rust语言深度嵌入的枚举模式
1. Option枚举
如下为Option的定义
pub enum Option<T> {
/// No value.
None,
/// Some value of type `T`.
Some(T),
}
按照枚举模式的特征思考总结:
- 特征一、Option表达的是可选的语义,没有值就是None,有值就是Some(T).
- 特征二、泛型枚举,泛型值是T
- 特征三、无枚举约束,可以涵盖所有类型及自定义类型
- 特征四、自定义的函数,Option定义了一系列的函数
- 枚举值判断,is_none、is_some
- 类型转换,as_deref、as_deref_mut、as_mut、as_pin_mut、ok_or、ok_or_else(转result类型)、
- 获取值,get_or_insert、get_or_insert_default、get_or_insert_with、cloned、copyed、unwraper、unwraper_or、unwraper_or_default、unwraper_or_else
- 函数式函数,filter、map、map_or、map_or_else、flattern、take、unzip、zip、zip_with
- 迭代函数: iter、iter_mut
- 关系函数:and、and_then、or、or_else
- 特殊函数:expect(设置Panic返回)、replace
- 作为函数返回值:例如所有的collection的取值,例如Vec类Pop、first、last、get、take
2. Result枚举
如下为Result的定义
pub enum Result<T, E> {
/// Contains the success value
Ok(T),
/// Contains the error value
Err(E),
}
按照枚举模式的特征思考总结:
- 特征一、Result表达的语义是异常处理机制,正常就是Ok(T),异常就是Err(E).
- 特征二、泛型枚举,Result有2个泛型定义,T和E
- 特征三、无枚举约束,可以涵盖所有类型及自定义类型
- 特征四、自定义的函数,Result定义了一系列的函数
- 枚举值判断,is_err、is_err_and、is_ok、is_ok_and
- 类型转换,as_deref、as_deref_mut、as_mut、as_ref、ok(转Option类型)、
- 获取值,cloned、copyed、unwraper、unwraper_or、unwraper_err、unwraper_err_default、unwraper_or、unwraper_or_else、unwraper_or_default、
- 函数式函数,map、map_or、map_err、flattern
- 迭代函数: iter、iter_mut
- 关系函数:and、and_then、or、or_else
- 特殊函数:expect、expect_err
- 作为函数返回值:例如fs文件操作,copy、read、write的返回都是result
3. Cow枚举
如下为Cow的定义
pub enum Cow<'a, B: ?Sized + 'a>
where
B: ToOwned,
{
/// Borrowed data.
Borrowed(&'a B),
/// Owned data.
Owned( <B as ToOwned>::Owned),
}
pub trait ToOwned {
type Owned: Borrow<Self>;
/// Creates owned data from borrowed data, usually by cloning.
fn to_owned(&self) -> Self::Owned;
/// Uses borrowed data to replace owned data, usually by cloning.
fn clone_into(&self, target: &mut Self::Owned) {
*target = self.to_owned();
}
}
按照枚举模式的特征思考总结:
- 特征一、Cow表达的语义写时拷贝,引用定义是Borrowed,持有值定义是Owned
- 特征二、泛型枚举,定义泛型B
- 特征三、有枚举约束,泛型B必须实现 ToOwned trait,B类型可以是str、CStr、OsStr、path、[T]
- 特征四、自定义的函数,Result定义了一系列的函数
- 枚举值判断,is_owned、is_borrowed
- 类型转换,into_owned、to_mut
- 作为函数返回值:主要是满足泛型B约束,在操作中延迟写
4 小结
在其它语言中,枚举很少有这样的关键语言角色,把语言中的枚举作为模式并按这样的思维套路来学习模仿,有事半功倍的效果。
枚举模式背后的逻辑是每种语言的思维不一样,学习语言也在学习背后的思维逻辑。
类似的例子还有《rust所有权:Move、Copy、Borrow语义》的总结“rust所有权是基础,背后的逻辑是相对于其它语言需要增加的一个思维环节,如果写代码的时候不思考这个环节,写出来的代码编译不过的概率很大,会经常在这里跌跤子”。