GoRust学习笔记

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

2018-11-23  本文已影响232人  黄耀东_c1d2

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  //此处若返回()则没有问题
    }
上一篇下一篇

猜你喜欢

热点阅读