«

Rust进阶 - 用枚举创建有意义的数

ljierui 发布于 阅读:59 技术杂谈


枚举解释

Rust中的枚举可以封装多个选择,不过它们表现得与常规结构很相似:

- 它们可以有trait和函数的impl块。
- 匿名和命名属性可以有不同的值。

实现过程

// 使用枚举创建有意义的数
use std::io;

// 声明一个包含一些数据的枚举
// Rust的enum可以有任何值,而不仅仅是数值,可以有命名属性
pub enum ApplicationError{
    Code{full:usize,short:u16},
    Message(String),
    IOWrapper(io::Error),
    Unknow
}

// 实现一个简单的函数
impl ApplicationError{
    pub fn print_kind(&self, mut to:&mut impl io::Write) -> io::Result<()>{
        let kind = match self{
            ApplicationError::Code{full:_ , short:_} => "Code",
            ApplicationError::Unknow => "Unknown",
            ApplicationError::IOWrapper(_) => "IOWrapper",
            ApplicationError::Message(_) => "Message"
        };
        write!(&mut to ,"{}", kind)?;
        Ok(())
    }
}

// 对enum进行处理
pub fn do_work(choice:i32) -> Result<(), ApplicationError> {
    if choice < -100{
        Err(ApplicationError::IOWrapper(io::Error::from(io::ErrorKind::Other)))
    }else if choice==42{
        Err(ApplicationError::Code { full: choice as usize, short: (choice % u16::max_value() as i32) as u16 })
    }else if choice > 42 {
        Err(ApplicationError::Message(format!("{} lead to a terrible error",choice)))
    }else {
        Err(ApplicationError::Unknow)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io;

    #[test]
    fn test_do_work(){
        let choice = 10;
        if let Err(error) = do_work(choice) {
            match error {
                ApplicationError::Code { full:code, short:_ } => 
                assert_eq!(choice as usize ,code),
                ApplicationError::Unknow|
                ApplicationError::IOWrapper(_) => assert!(choice < 42),
                ApplicationError::Message(msg) =>
                assert_eq!(format!(
                    "{} lead to a terrible error",choice
                ),msg)
            }
        }
    }

    #[test]
    fn test_application_error_get_kind(){
        let mut target = vec![];
        let _ = ApplicationError::Code { full: 100, short: 100 }.print_kind(&mut target);
        assert_eq!(String::from_utf8(target).unwrap(),"Code".to_string());

        let mut target = vec![];
        let _ = ApplicationError::Message("0".to_string()).print_kind(&mut target);
        assert_eq!(String::from_utf8(target).unwrap(),"Message".to_string());

        let mut target = vec![];
        let _ = ApplicationError::Unknow.print_kind(&mut target);
        assert_eq!(String::from_utf8(target).unwrap(),"Unknown".to_string());

        let mut target = vec![];
        let error = io::Error::from(io::ErrorKind::WriteZero);
        let _ = ApplicationError::IOWrapper(error).print_kind(&mut target);
        assert_eq!(String::from_utf8(target).unwrap(),"IOWrapper".to_string());
    }
}

rust语言学习