布尔类型,字符类型,数值类型,数组,元组
在 Rust 中,每一个值都属于某一个数据类型(data type),这告诉 Rust 它被指定为何种数据,以便明确数据处理方式。我们将看到两类数据类型子集:标量(scalar)和复合(compound),Rust 是 静态类型(statically typed)语言,也就是说在编译时就必须知道所有变量的类型。
正如其他大部分编程语言一样,Rust 中的布尔类型有两个可能的值:true 和 false。Rust中的布尔类型使用 bool 表示。例如:
let is_she_love_me = false;
let mut is_he_love_me: bool = true;
bool类型被用的最多的地方就是在if表达式里了。
在Rust中,一个char类型表示一个Unicode字符,这也就意味着,在某些语言里代表一个字符(8bit)的char,在Rust里实际上是四个字节(32bit)。 同时,我们可以将各种奇怪的非中文字符随心所欲的赋值给一个char类型。需要注意的是Rust中我们要用'来表示一个char,如果用"的话你得到的实际上是一个&'static str。下面是一些声明 char 值的例子:
let c = 'x';
let cc = '🐢';
和其他类C系的语言不一样,Rust用一种符号+位数的方式来表示其基本的数字类型。可能你习惯了int、double、float之类的表示法,Rust的表示法需要你稍微适应一下。
整数是一个没有小数部分的数字,并且每一个变体都可以是有符号或无符号的,并有一个明确的大小。有符号 和 无符号 代表数字能否为负值,另外,自适应类型isize和 usize 类型依赖运行程序的计算机架构:64 位架构上它们是 64 位的,32 位架构上它们是 32 位的。
| 长度 | 有符号 | 无符号 |
|---|---|---|
| 8-bit | i8 | u8 |
| 16-bit | i16 | u16 |
| 32-bit | i32 | u32 |
| 64-bit | i64 | u64 |
| 128-bit | i128 | u128 |
| arch | isize | usize |
Rust 也有两个原生的 浮点数(floating-point numbers)类型,它们是带小数点的数字。Rust 的浮点数类型是 f32 和 f64,分别占 32 位和 64 位。默认类型是 f64,因为在现代 CPU 中,它与 f32 速度几乎一样,不过精度更高。所有的浮点型都是有符号的,f32 是单精度浮点数,f64是双精度浮点数。浮点数的实例:
fn main() {
let x = 2.0; // f64
let y: f32 = 3.0; // f32
}
复合类型(Compound types)可以将多个值组合成一个类型。Rust有两个原生的复合类型:元组(tuple)和数组(array)。
元组是一个将多个其他类型的值组合进一个复合类型的主要方式。元组长度固定:一旦声明,其长度不会增大或缩小。
我们使用包含在圆括号中的逗号分隔的值列表来创建一个元组。元组中的每一个位置都有一个类型,而且这些不同值的类型也不必是相同的。这个例子中使用了可选的类型注解:
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
}
tup 变量绑定到整个元组上,因为元组是一个单独的复合元素。为了从元组中获取单个值,可以使用模式匹配(pattern matching)来解构(destructure)元组值,像这样:
fn main() {
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {y}");
}
程序首先创建了一个元组并绑定到 tup 变量上。接着使用了let 和一个模式将tup 分成了三个不同的变量,x、y 和 z。这叫做 解构(destructuring),因为它将一个元组拆成了三个部分。最后,程序打印出了 y 的值,也就是 6.4。
我们也可以使用点号(.)后跟值的索引来直接访问它们。例如:
fn main() {
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
}
这个程序创建了一个元组,x,然后使用其各自的索引访问元组中的每个元素。跟大多数编程语言一样,元组的第一个索引值是 0。
与元组不同,数组中的每个元素的类型必须相同。Rust 中的数组与一些其他语言中的数组不同,Rust 中的数组长度是固定的。
Rust的数组是被表示为[T;N]。其中N表示数组大小,并且这个大小一定是个编译时就能获得的整数值,T表示泛型类型,即任意类型。我们可以这么来声明和使用一个数组:
let a = [8, 9, 10];
let b: [u8;3] = [8, 6, 5];
数组是可以在栈 (stack) 上分配的已知固定大小的单个内存块。可以使用索引来访问数组的元素,像这样:
fn main() {
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
}
数组非常有用,但是在使用上不够灵活,后面会详细讨论动态数组 Vec(vec是标准库提供的一个允许增长和缩小长度的类似数组的集合类型)。
字符串类型,切片,HashMap类型,结构体,将在后面章节详细讨论。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!