跳至主要內容

数据类型

ColorSky大约 5 分钟笔记Rust

标量类型

一个标量类型代表一个单个值

整数类型

没有小数部分的数

  1. 无符号类型以u开头,比如u32
  2. 有符号类型以i开头,比如i32
  • 有符号Signed,范围为2n1-2^{n-1}2n12^{n-1}
  • 无符号UnSigned,范围为002n12^n-1

整数类型列表:

长度有符号无符号
8 位i8u8
16 位i16u16
32 位i32u32
64 位i64u64
128 位i128u128
archisizeusize

usize 和 isize 类型

由计算机的架构决定,32 位系统中usize相当于u32

整数字面值

进制开头举例
null12_345
十六0x0xff
0o0o77
0b0b10
Byteb''b'A'

整数溢出

  • 列如,u8的范围为 0-255,如果let a = 256,则
    1. 在调试模式(debug)下编译,rust 会检测整数溢出,如有出现整数溢出则运行时panic
    2. 在发布模式(--release)下编译,rust 不会检测可能的panic
      • 如果发生溢出则进行循环操作, 256->0, 257->1

浮点类型

含有小数部分的数

  • f32 :32 位,单精度
  • f64 :64 位,双精度(默认)

布尔类型

  • true
  • flase

字符类型

  • char类型.占用 4 字节大小,字面值用单引号
  • Unicode 标量值,范围:
    1. U+0000 到 U+D7FF
    2. U+E000 到 U+10FFFF

复合类型

  1. 元组(Tuple)
    • 可以将多个类型的多个值放在一个类型里
    • 长度固定, 声明之后无法修改
    let tup: (i32, f64, u8) = (500, 5.5, 255);
    //访问tuple中的值,`.0`代表元组中的第一个元素的索引
    print!("NO.1: {}, NO2.: {}, NO.3:{}",tup.0, tup.1, tup.2);
    
    • 获取 tuple 的元素值
    //模式匹配
    let tup: (i32, f64, u8) = (500, 5.5, 255);
    let (a, b ,c);
    
  2. 数组
    • 每个元素的类型必须相同
    • 长度固定, 声明之后无法修改
    • EG:
    let months = [
        "一月",
        "二月",
    ];
    
    • 数组类型表示
      //第一种,'[a, b]'内指定,a为类型,b为长度
      let a:[i32, 5] = [1, 2, 3, 4, 5];
      //第二种,'[a, b]'中,a为初始值,b为长度
      let a = [3; 5];
      //这个相当于
      let a = [3, 3, 3, 3, 3];
      
    • 访问数组元素: 使用索引访问
    let a = ["one", "two", "three", "four"];
    print!("first of a is {}", a[0]);
    
    • 如果在不得已的情况下索引超出了数组的最大元素时,rust 不允许其访问其他内存,所以程序将报错
    //假设编译通过
    //但是程序运行会报错panic
    let a: [&str; 4] = ["one", "two", "three", "four"];
    let index = [4, 5, 6, 7];
    print!("first of a is {}", a[index[1]]);
    

String 类型

  • 比那些基础标量更复杂
  • 存储在堆(heap)上
  • 标准库提供
let s = String::from("hello");
  • 深拷贝内容
let s = String::from("hello");
let s1 = s.clone()

枚举类型

  • 自定义的类型
enum IpAddrKind {
    v4,
    v6
}
fn main() {
    //创建枚举值
    let four = IpAddrKind::v4;
    let six = IpAddrKind::v6;
}

常用集合

Vector

  • Vec<T> 叫做 Vector

    • 由标准库提供,可以储存多个值
    • 只能存储相同类型的值
    • 值在内存中连续存放
    /*创建*/
    //方法1
    let mut a: Vec<i32> = Vec::new();
    a.push(1);
    a.push(2);
    //方法2
    let mut a: Vec<i32> = vec![1, 2, 3, 4, 5];
    
    //读取Vector里面的元素
    
    println!("{}", a[0]); //1.索引
    println!("{:#?}", a.get(0)); //2.get()方法,返回Option<>类型的值(Some/None)
    
  • HashMap

    • 用来储存键值对
    • 将数据存在堆内存上
    use std::collections::HashMap;
    
    fn main() {
        //方法一
        let mut dict = HashMap::new();//HashMap需要知道键值对的类型
        dict.insert(String::from("Color"), 10);
    
        //方法二
        let mut dict: HashMap<String, u32> = HashMap::new();
    }
    
    • 另一种创建 HashMap 的方法:collect 方法

      • 在元素类型为 Tuple 的 Vector 上使用 collect 方法,可以组建一个 HashMap:
        • 要求 Tuple 有两个值,一个作为 Key,一个作为 Vuale
        • collect 方法可以把数据整合成许多集合类型,包括 HashMap,返回值需要显式指明类型
      let teams = vec![String::from("bule"), String::from("Color")];
      let intial_dict = vec![5, 10];
      let dict: HashMap<_, _> = teams.iter().zip(intial_dict.iter()).collect();
      
    • 访问 HashMap 中的值

      • get 方法:参数K,返回Option<&V>
    • HashMap 的大小可变

    • 每个 K 只能对应一个 V

    • 更新 HashMap 中的数据

      1. K 已经存在,对应一个 V

        • 替换现有的 V
        let mut scores = HashMap::new();
        scores.insert(String::from("blue"), 5);
        scores.insert(String::from("blue"), 10);
        
        //println!("{:#?}", scores)
        //blue对应值为10
        
        • 保留现有的 V
        let mut scores = HashMap::new();
        scores.insert(String::from("blue"), 5);
        scores.entry(String::from("red")).or_insert(25);
        //entry方法检测key是否已存在对应的value,不存在则执行方法or_insert
        //or_insert方法将default参数作为key的新值
        
        scores.entry(String::from("blue")).or_insert(10);
        
        • 理解:

          fn main() {
              let text = "hello rust world";
              //println!("{:#?}", text.split_whitespace());
              let mut map = std::collections::HashMap::new();
          
              for word in text.split_whitespace() {
                  let count = map.entry(word).or_insert(0);
                  //println!("{:#?}", word);
              *count += 1;
              }
          
              println!("{:#?}", map)
          }
          
        • 合并现有的 V 和新的 V

      2. K 不存在

        • 添加一对 K,V

结构体 struct

  • 定义结构体
  • 结构体可以定义在任何地方
struct User {
    active: bool,
    username: String,
    email: String,
    uid: u32,
}
  • 创建结构体实例
let mut user_one = User {
    active: true,
    username: String::from("name"),
    email: String::from("ecample@domain.com"),
    uid: 1,
};
//如果结构体可变,更改结构体中的键值对
user_one.email = String::from("example@domain.com");
  • 字段初始化简写语法
fn build_user(username: String, email: String) -> User {
    User {
        username,
        email,
        active: true,
        uid: 1,
    }
}

传入的username参数与 User 结构体中的username名称相同,这样就无需再写email: email

  • 使用结构体更新语法从其他的实例创建实例
fn main() {
    let user = User {
        username: String::from("name"),
        email: String::from("example@domain.com"),
        active: true,
        uid: 1,
    };
    //--snip--
    let usert = User {
        active: user.active,
        email: user.email,
        uid: 2,
        username: String::from("named"),
    };
}