美文网首页GoRust学习笔记
Rust语言学习小记(结构体、枚举)

Rust语言学习小记(结构体、枚举)

作者: 黄耀东_c1d2 | 来源:发表于2018-11-23 09:39 被阅读232次

    3. 结构体

    3.1 结构提可变性:结构体不能单独声明某个字段的可变性,只能声明整个实例的可变性。

    3.2 各种赋值语法

        //声明结构体
        struct User {
            name : String,
            email : String,
            sign_in_count : u32,
        }
        
        //声明元组结构体
        struct Color(i32, i32, i32);
        struct MyUnit(); //没有任何字段的单元结构体   
    
        //基础的赋值
        let u1 = User{
            name : String::from("name"),
            email : String::from("test@mail.com"),
            sign_in_count : 3,
        };
        
        //变量名与字段名相同时的赋值
       let name = String::from("Hello world");
       let email = String::from("mail");
       let u2 = {
           name,   //此处会获取name指向的String值的所有权
           email,   //此处会获取email指向的String值的所有权
           sign_in_count : 1,
       };
      
       //结构体更新语法
      let u3 = User {
          name : String::from("my name"),
          email : String::from("my mail"),   //name和email字段需要所有权,为使u2能正常使用,此处需重新生成这两个字段
          ..u2
      };
    

    3.3 println!的debug结构及利用宏派生trait
    在println!宏中使用{:?}格式字符串可输出入参的debug格式,该行为将调用入参所示先的Debug Trait的对应功能。使结构体便捷的实现Debug Trait的功能的方法是:在结构体声明前加上#[derive(Debug)]注解。

    3.4 方法语法
    方法声明需放在impl语句块中,且第一个参数必须为self。impl语句块可以有多个。

    struct User {
        name : String,
    }
    
    impl User {
        fn method(&self) -> String {
              //do something
        }
    }
    

    若impl语句块中声明的函数,第一个参数不为self,它就是关联函数。该函数可以根据结构体名通过::来引用。

    4. 枚举

    4.1 rust的枚举中,不同的枚举值可以携带不同类型及数量的数据

    enum Message{
        QUIT,
        MOVE {x : i32, y : i32}, //匿名的结构体
        WRITE(String),
    }
    

    4.2 Rust中使用Option枚举表示可能没有的值

    enum Option<T>{
       Some(T),
       None,
    }
    // 使用
    let some = Some(1);
    let none : Option<i32> = None; //使用None赋值时需要显示申明变量类型
    

    4.3 模式匹配
    使用match表达式或者if let语句可以进行模式匹配

    match value {
        pattern1 => result,
        pattern2(variable) => {
            //do something
            result  
        },
        _ => result,   //match语句是又穷的,需要穷尽所有模式。如果只想捕获某几个模式而忽
                       //略其他的,则需将要捕获的模式放在最前面,然后利用 _ 通配符指代
                      //所有的其他模式
    };
    
    if let pattern(variable) = value {   //if let使用 = 来区分模式和值。=左边是模式,
                                         // 右边是值
        result
    }else{
        result2
    }
    

    4.3 match表达式重新开启了一个作用域,因此,如果在match后直接使用变量,则变量的所有权会被移动到新的作用域中,在之后的代码中将无法使用

        let m = Message::MESSAGE(String::from("Hello world"));
        match m {   //此处若使用&m,即m的引用,则不会有问题
            Message::MESSAGE(message) => println!("{}", message),
            _ => println!("nothing"),
        }
    
        match m {  //编译报错,m已被移动了
            Message::MESSAGE(message) => println!("{}", message),
            _ => ()
        }
    

    4.4 match表达式各分支的返回结果必须一致,否则会编译报错

        let m = Message::MESSAGE(String::from("Hello world"));
        match m {   //报错,2与()类型不一致
            Message::MESSAGE(message) => println!("{}", message),
            _ => 2  //此处若返回()则没有问题
        }
    

    相关文章

      网友评论

        本文标题:Rust语言学习小记(结构体、枚举)

        本文链接:https://www.haomeiwen.com/subject/rinofqtx.html