Rust-数据类型

Rust数据类型

标量和复合类型

  • Rust是静态编译语言,在编译时必须知道所有变量的类型

    1. 基于使用的值编译器通常能够推断出变量的具体类型

    2. 但如果可能的类型比较多,就必须标注变量的具体类型,否则在编译期就会报错,例:

      fn main() {
          let test = "65".parse().expect("Not a number!");
      }
      

编译报错

修改为:

fn main() {
    let test:u32 = "65".parse().expect("Not a number!");
    println!("{}",test);
}

更改为:

指定test变量的类型为u32类型,成功编译运行

标量

  • 一个标量类型代表一个单个的值
  • Rust有四个主要的标量类型:
    • 整数类型
    • 浮点类型
    • 布尔类型
    • 字符类型

整数类型

  • 整数类型没有小数部分

  • 例如u32就是一个无符号的整数类型,占据32位的空间

  • 无符号整数类型以u开头

  • 有符号的整数类型以i开头

  • Rust的整数类型如下:

    • 每种都分iu,以及固定的位数
  • isizeusize类型

    • isize和usize的位数由运行程序的计算机的架构所决定
      • 如果是64位计算机,那就是64位的
      • 使用这两种类型的场景不多,主要是对某种集合进行索引操作

整数字面值

  • 除了byte类型外,所有数值字面值都允许使用类型后缀
    • 例如57u8
  • 如果不清楚应该使用哪种类型,可以使用Rust中相应的默认类型:
    • 整数的默认类型就是i32
      • 即使在64位系统中整体运行速度也很快

整数溢出

例如u8的范围是0~255,如果把一个u8变量的值设为256,那么:

  • 调试模式下编译(debug)

    Rust会检查整数溢出,如果发生溢出,程序在运行时就会panic

  • 发布模式下编译(release)

    Rust不会检查可能导致panic的整数溢出:

    • 如果溢出发生,Rust会执行环绕操作:
      • 256变成0,257变成1
    • 但程序不会panic

浮点类型

  • Rust有两种基础的浮点类型:
    • f32 ,32位,单精度
    • f64 ,64位,双精度
  • Rust的浮点类型使用了IEEE-754标准来表述
  • f64是默认类型,因为在现代cpu上f64f32的速度差不多,而且精度更高,例子:

数值操作

  • 加减乘除余:

    //加
    let sum = 45 + 56;
    //减
    let difference = 78.0 - 45.2;
    //乘
    let product = 45 * 34;
    //除
    let quotient = 89 / 12;
    //取余
    let reminder = 65 % 4;
    

    与其他语言无区别

布尔类型

  • Rust的布尔类型也有两个值:

    • true
    • false
  • 大小为一个字节

  • 符号为bool

    //两种声明bool值的方式
    let flag_t = true;
    let flag_f:bool = false;
    

字符类型

  • Rust中的char类型用来描述语言中最基础的字符

  • 字符类型的字面值使用单引号

  • 占用四个字节

  • 是Unicode标量值,可以表示比ASCLL多得多的字符内容:拼音,中日韩文,零长度空白字符,emoji表情等:

  • 但Unicode并没有字符的概念,因此直觉上认为的字符也许和Rust中的概念并不相符:

        let a:char = 's';
        let b = '在';
        let c = '😂';
    

复合类型

  • 复合类型可以将多个值放在一个类型里
  • Rust提供了两种基本的数据类型:
    • 元组(Tuple)
    • 数组

Tuple(元组)

  • Tuple可以将多种类型的多个值放在一个类型中

  • Tuple的长度是固定的,一旦声明后就不可改变

  • 创建Tuple:

    • 在小括号中,将值用逗号分开

    • Tuple 的每个位置都对应一个类型, Tuple中的各元素类型不必相同:

      fn main() {
          let tup:(i32,f64,u8) = (78,45.4,1);
      }
      
    • 获取Tuple中的值:

      • 可以使用模式匹配来解构(destructure)一个Tuple来获取元素的值

        fn main() {
            let tup:(i32,f64,u8) = (78,45.4,1);
            let (x,y,z) = tup;
            println!("{},{},{}",x,y,z);
        }
        

    • 访问Tuple中的值

      • 对Tuple变量使用点标记法,后接元素的索引号

        fn main() {
            let tup:(i32,f64,u8) = (78,45.4,1);
            println!("{},{},{}",tup.0,tup.1,tup.2);
        }
        

数组

  • 数组可以将多个值放在一个类型里

  • 数组中的每个元素的类型必须相同

  • 数组的长度也是固定的,声明后不可变

  • 声明数组

    • 在中括号里,各个值使用逗号分开:

      let arr = [1,2,3,4,8,9];
      
  • 数组的用处

    • 如果想让你的数组存放在stack(栈)上而不是heap上,或者像保证有固定数量的元素,这时使用数组更有好处

    • 但是数组没有Vector灵活

      • Vector和数组类似,它由便准库提供
      • Vector的长度是可变的
      • 如果不确定应该使用数组还是Vector时,大概率应该使用Vector
    • 数组的类型:

      let a:[i32;5] = [1,6,8,4,3];
      
      • 另一种声明数组的方式(特殊)

        • 如果数组的每个元素都相同,那么在中括号中指定初始值,初始值后是一个分号,最后是数组的长度:

          let a = [3;5];//那么此语句等价为:
          let a = [3,3,3,3,3];
          
    • 访问数组的元素

      • 数组是Stack上分配的单个块的内存

      • 可以使用索引来访问数组的元素:

        let arr = [1,2,3,4,8,9];
        let a = arr[0];//1
        let y = arr[4];//8
        
    • Rust中如果访问超出数组索引的元素则会报错,不允许访问,这与C/C++是不同的

毛小川's Blog

环游是无趣~


2022-05-31