Rust基础复习笔记(二)结构体、枚举与匹配
这一部分涉及到两种新的数据结构:结构体与枚举类型,和一种新的控制流:匹配。
对应The Rust Programming Language第4-5章的内容。代码来自前书。
1.结构体
1.1结构体的定义
一般结构体的定义与其他语言类似:
struct User {
  username: String,
  email: String,
  sign_in_count: u64,
  active: bool,
}
//注意类型名在冒号后声明,变量之间用逗号分隔
如果要声明一个以上的结构体,
可以直接声明:
let mut user1 = User {
    email: String::from("someone@example.com"),      //保留结构体本身对字符串的所有权
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};
//可以更改里面的值
user1.email = String::from("anotheremail@example.com");
可以采用构造函数。简单的方法是将参数表里的名称直接对应。
fn build_user(email: String, username: String) -> User {
    User {
      email,            //取代email: email,
      username,
      active:true,
      sign_in_count:1,
      }
}
从已有的结构体改变几个值以创建新的
fn main() {
    let user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
    let user2 = User {
        email: String::from("another@example.com"),
        username: String::from("anotherusername567"),
        ..user1      //这里代表使用user1的其他元素的值
    };
}
另外一种简单的元组结构体使用方法如下:
fn main() {
    struct Color(i32, i32, i32);
    struct Point(i32, i32, i32);
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
    //注意black和origin是不同的类型,是不能相互运算的。
}
1.2结构体的使用
打印结构体需要启用Debug属性
#[derive(Debug)]      //在这里启用
struct Rectangle {
    width: u32,
    height: u32,
}
fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };
    println!("rect1 is {:?}", rect1);
    println!("rect1 is {:#?}", rect1);//这种方式打印会更加清晰的对输出进行分行操作
}
添加方法:在impl代码块中声明
impl Rectangle {
    fn area(&self) -> u32 {      //参数表中第一项是&self(可变的是&mut self),不含&self的被称为友元函数(?)。
        self.width * self.height
    }
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
    //这种函数一般用来构造。这两个函数也可以分写在不同的impl块中,不过现在没必要。
}
2.枚举
2.1一般枚举类
在enum块中声明,还可以携带一个数据类型(类似于union),这个类型也可以是Tuple或自定义的Struct
enum IpAddr {
    V4(String),
    V6(String),      //没有类型,逗号分隔
}
impl IpAddr{
  fn call(&self){
      /*Anything*/
  }
}
//甚至也可以定义方法
let home = IpAddr::V4(String::from("127.0.0.1");      //声明枚举类型变量及其附属数据
home.call();
Option
rust的基本类型里没有None,但是可以通过Option
let a1 = Some(1);
let a2:Option<i32> = None;
let a3 = 1;
这三者,a1和a3分属不同类型,不能相加
Option
匹配
枚举类与匹配天然搭配使用。
#[derive(Debug)]
enum UsState {
    Alabama,
    Alaska,
    // --snip--
}
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}
//硬币类和四分钱硬币分的各种产地
fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            println!("State quarter from {:?}!", state);//使用参数
            25
        }
    }
}
fn main() {
    value_in_cents(Coin::Quarter(UsState::Alaska));
}
要注意匹配必须把所有情况都列举出来。否则要用占位符:
let some_u8_value = 0u8;
    match some_u8_value {
        1 => println!("one"),
        3 => println!("three"),
        5 => println!("five"),
        7 => println!("seven"),
        _ => (),      //'_'代表占位符,()代表什么也不做
    }
if let匹配,类似于if。可以用来简化match书写的代码。
let mut count = 0;
if let Coin::Quarter(state) = coin {
  println("Quarter from {:?}", state);
} else {
  count += 1;
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号