数值类型

Rust的数值类型包括整数和浮点数。有如下几种类型:

长度有符号无符号浮点数
8-biti8u8
16-biti16u16
32-biti32(默认)u32f32
64-biti64u64f64(默认)
128-biti128u128
wordisizeusize

注: word表示一个机器字长,通常是一个指针的大小,大小和机器有关。64位机器的word是64-bit,32位机器的word是32-bit。

可以在数值字面量后加上类型来表示该类型的数值。例如:

fn main(){
  let _a = 33i32;    // 直接加类型后缀
  let _b = 33_i32;   // 使用_分隔数值和类型
  let _c = 33_isize;
  let _d = 33_f32;
}

如果数值较长,可以在任意位置处使用下划线_划分数值,增加可读性。

fn main(){
  let _a = 33_333_33_i32;
  let _b = 3_333_333_i32;
  let _c = 3_333_333f32;
}

当不明确指定变量的类型,也不明确指定数值字面量的类型后缀,Rust默认将整数当作i32类型,浮点数当作f64类型

fn main(){
  // 等价于 let _a: i32 = 33_i32;
  let _a = 33;
  
  // 等价于let _b: f64 = 64.123_f64;
  let _b = 64.123;
}

每种数值类型都有所能存储的最大数值和最小数值。当超出类型的有效范围时,Rust将报错(panic)。例如u8类型的范围是0-255,它无法存储256。

fn main() {
  let n: i32 = std::i32::MAX;  // i32类型的最大值
  println!("{}", n + 1);     // 编译错误,溢出
}

Rust允许使用0b 0o 0x来表示二进制、八进制和十六进制的整数

fn main(){
  let a = 0b101_i32;  // 二进制整数,i32类型
  let b = 0o17;       // 八进制整数,i32类型
  let c = 0xac;       // 十六进制整数,i32类型
  println!("{}, {}, {}", a, b, c);  // 5, 15, 172
}

数值类型之间默认不会隐式转换,如果需要转换数值类型,可手动使用as进行转换(as主要用于原始数据类型间的类型转换)。例如3_i32 as u8表示将i32类型的3转换为u8类型。需注意,宽类型数值转为窄类型数值时,如果溢出,则从高位截断。

fn main(){
  assert_eq!(10_i8 as u16, 10_u16);
  assert_eq!(2525_u16 as i16, 2525_i16);
  
  // 有符号类型->有符号类型
  assert_eq!(-1_i16 as i32, -1_i32);
  // 有符号到无符号类型
  assert_eq!(-1_i32 as u8, 255_u8);
  
  // 范围溢出,截断
  assert_eq!(1000_i16 as u8, 232_u8);
  
  // 浮点数转整数,小数部分被丢弃
  assert_eq!(33.33_f32 as u8, 33_u8);
}

Rust数值是一种类型的值,每种类型有自己的方法,因此数值也可以调用它们具有的方法。

fn main(){
  // 需注意,下面的数值都加上了类型后缀。
  // 这是因为在调用方法的时候,需要知道值的
  // 所属类型才能找到这种类型具有的方法
  println!("{}", 3_u8.pow(2));      // 9
  println!("{}", (-3_i32).abs());   // 3
  // 4,计算45的二进制中有多少个1
  println!("{}", 45i32.count_ones());  // 4
}

Rust将字节字面量存储为u8类型,字节字面量的表示方式为b'X'(b后面使用单引号包围单个ASCII字符)。

例如A的ASCII码为65,那么b'A'完全等价于65u8

fn main(){
  let a = b'A';     // a的类型自动推导为u8
  let b = a - 65;   // b的类型也自动推导为u8
  println!("{}, {}", a, b);  // 65, 0
}

需注意,某些特殊ASCII字符需要使用反斜线转义,例如b'\n', b'\'', b'\\'。有些控制类的字符无法直接写出来,此时可以使用十六进制法来表示,例如b'\x1b'表示ESC按键的控制符。