基本数据类型
Rust是一门静态类型
语言,这意味着在编译期就需要知道所有值的类型。虽然在多数情况下编译器能够推测出你想要使用的类型,但随着程序的庞大和复杂,变量类型的不确定性也就更高了,因此声明数据时进行类型标注
是有必要的。这里主要介绍两大类数据类型:标量类型
、复合类型
。
标量类型
标量类型标识单个值
。Rust标量类型包括:整型
、浮点型
、布尔型
、字符型
。
1. 整型
整型是不包含小数部分的数字,整型还分为有符号和无符号类型。有符号类型以i
开头即integer
,表示这个整数是否可以取负数;无符号类型以u
开头即unsigned
,表示这个整数只表示正整数。
长度 | 有符号型 | 无符号型 |
---|---|---|
8位 | i8 | u8 |
16位 | i16 | u16 |
32位 | i32 | u32 |
64位 | i64 | u64 |
128位 | i128 | u128 |
arch | isize | usize |
有符号类型表示的取值范围是: -(2^n^ -1) ~ 2^n-1^ - 1,无符号类型表示的取值范围是:0 ~ 2^n^ - 1,n代表该数据类型的位数。如i8
的取值范围为:-128 ~ 127,u8
的取值范围则是:0 ~ 255。Rust 的整型默认是 i32
。isize
和 usize
的主要应用场景是用作某些集合的索引。
整型溢出
整型溢出
是指给整型变量赋的值超出了变量的取值范围。如将一个u8
赋值 256。则会发生整型溢出。整型溢出可能导致发生以下两种行为之一:
- 在调试模式 的编译期,编译器会检查整型溢出,如果存在会导致程序panic。
- 当使用
--release
时,编译器会忽略整型溢出,而采取一种二进制补码的方式将该数值转换为该类型取值范围内的最小值。如u8
时为256,将被转换后为0,程序并不会panic,但将会得到非期望的值,不应该依赖补码处理整型溢出。
要显式处理溢出的可能性,可以使用标准库针对原始数字类型提供的以下一系列方法:
- 使用 wrapping_* 方法在所有模式下进行包裹,例如 wrapping_add
- 如果使用 checked_* 方法时发生溢出,则返回 None 值
- 使用 overflowing_* 方法返回该值和一个指示是否存在溢出的布尔值
- 使用 saturating_* 方法使值达到最小值或最大值
2. 浮点型
浮点型就是含有小数部分的整数。在Rust中浮点类型分为单精度和双精度两种,分别对应f32
和f64
。区别在于位数不同,Rust默认的浮点类型是f64,在现代计算机中,双精度浮点数精度更高,速度与f32基本相同。
fn main() {
let x = 2.0; // f64
let y: f32 = 3.0; // f32
}
3. 数字运算
Rust的所有的数字类型都支持基本的数学运算,运算符包括加、减、乘、除、取模等。整数除法会向下取整。此外浮点数和整数之间可以进行运算(取模操作除外),运算结果为浮点数。示例如下
fn main() {
let x = 10;
let y = 2;
let z = 5;
let a = 2.0;
//基本加减乘除
println!("x+y={}",x+y);
println!("x-y={}",x-y);
println!("x/y={}",x/y);
println!("x*y={}",x*y);
//整数相除向下取整
println!("z/y={}",z/y); //2.5向下取整,所以输出2
//浮点数与整数运算结果取整数
println!("x*a={}",x*y); //20
//整数和浮点数之间不能进行取模运算
println!("y%x={}",y%x); // 2
//no implementation for `{float} % {integer}`
println!("a%z={}",a%z);
println!("z%a={}",z%a);
}
4. 布尔类型
和大多数语言一样,布尔类型只有两个值:true和false。具有显示声明的bool类型:
let t = true
let f:bool = false //显式声明
5. 字符类型
Rust 的 char
(字符)类型是该语言最基本的字母类型。 char
字面量采用单引号括起来,字符串字面量是用双引号括起来,字符大小为4字节(byte
)。
fn main() {
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '😻';
}
复合类型
在Rust中,将多个值组合在一起可以组成复合类型,常见的复合类型有元组(tuple)和数组(array)
1. 元组
元组是Rust中一个非常特殊的复合类型,它允许将多个不同类型
的值组合在一起。元组是固定长度的,一旦创建,元组中的元素数量和类型就不能改变。
创建元组:
let tupl1:(i32,f64,u8) = (500,6.4,1);
let tupl2:(i32,i32,u8) = (0,6,1);
访问元组。有两种方式访问元组中的元素:
- 模式匹配来解构,如
let (x,y,x) = tupl1
,x、y、z可为其他不重复名称。 - 通过
.
+ 索引(从0开始)访问。
let tupl:(i32,f64,u8) = (500,6.4,1);
let (x,y,z) = tupl;
println!("x = {},y = {},z = {}",x,y,z);
println!("x = {},y = {},z = {}",tupl.0,tupl.1,tupl.2);
特殊的元组:没有值或者只有一个值的元组称为单元类型(unit type),表示为()
。该值被称为单元值(unit value)。如果表达式不返回任何其他值,就隐式地返回单元值。
2. 数组
数组是Rust中一个重要的复合类型,它允许将多个相同类型
的值组合在一起。数组是固定长度的,一旦创建,数组中的元素数量和类型就不能改变。Rust标准库存在一种动态数组,称之为向量(vector)。如果不确定是使用数组还是 vector,那就应该使用一个 vector,但当你明确元素数量不需要改变时,数组会更加高效。
创建数组有很多方式:
//1.直接创建
let names = ["Bob","Alice","Carol"];
//2.标明类型。&str表示每个元素的类型,3表示数组的长度
let names: [&str; 3] = ["Bob","Alice","Carol"];
//3.当数组中的所有元素都相等时。3表示每个元素的值,5表示数组的长度
let a = [3; 5]; // [3, 3, 3, 3, 3]
访问数组的元素:
- 通过
[]
+ 索引访问数组的元素,索引从0开始。 - 当超出索引来访问时,会引起程序panic。
println!("The first element is {}",names[0]);
println!("The second element is {}",names[1]);
println!("The third element is {}",names[2]);
println!("The fourth element is {}",names[3]); //panic