数据类型
在 Rust 中,数据类型可以分为两类:基本数据类型(Primitive Types)和复合数据类型(Compound Types)。
- Rust 是静态编译语言,在编译时必须知道所有变量的类型。
- 基于使用的值,编译器通常能推断出类型。
- 但如果可能的类型比较多(例如把 String 转整数的 parse 方法),就必须添加类型的标注,否则编译会报错
基本数据类型(Primitive Types):
整数类型(Integer Types):
i8、i16、i32、i64、i128:有符号整数类型,分别表示 8、16、32、64 和 128 位的有符号整数。u8、u16、u32、u64、u128:无符号整数类型,分别表示 8、16、32、64 和 128 位的无符号整数。isize、usize:分别表示有符号和无符号整数,其大小取决于运行平台的位数。
- 有符号范围 :
- $2^n - 1$ 到 $2^n-1 -1$
- 无符号范围:
- 0到 $2^n - 1$
整数溢出 -例如:U8 的范围是 0-255,如果你把一个 U8 变量的值设次256,那么:
- 调试模式下编译:Rust 会检查整数溢出,如果发生溢出,程序在运行时就会 panic
-发布模式下(-release)编译:Rust 不会检查可能导致 panic 的整数溢出
- 如果溢出发生:Rust 会执行“环绕”操作:
- 256变成O,257变成1.
- 但程序不会 panic
- 如果溢出发生:Rust 会执行“环绕”操作:
浮点数类型(Floating-Point Types):
- Rust 有两种基础的浮点类型,也就是含有小数部分的类型
- f32,32位,单精度
- f64,64位,双精度
- Rust的浮点类型使用了 IEEE-754 标准来表述
- f64 是默认类型,因为在现代 CPU 上f64 和 f32的速度差不多,而且精度更高。
布尔类型(Boolean Type):
bool:表示布尔值,只能是true或false。一个字节大小。
字符类型(Character Type):
char:表示 Unicode 字符,占 4 个字节。
- Rust 中的 char 是一个 32 位的 Unicode 标量,能够表示所有 Unicode 字符。
- JavaScript 没有原生的 char 类型,字符实际上是 UTF-16 编码的字符串。单个字符可能占用 2 或 4 字节。
空类型(The Unit Type):
():也称为 unit 类型,表示空元组。
复合数据类型(Compound Types):
-
数组类型(Array Type):
[T; N]:表示包含 N 个元素、每个元素类型为 T 的数组。
-
元组类型(Tuple Type):
(T1, T2, ..., Tn):表示一个由多个不同类型的值组成的元组。
-
切片类型(Slice Type):
[T]:表示一个动态大小的数据序列切片,通常用于引用数组的一部分。
-
引用类型(Reference Type):
&T:表示对值的借用(引用),允许在不传递所有权的情况下访问值。&mut T:可变引用类型,允许通过引用修改值。
-
指针类型(Pointer Type):
*const T:不可变原始指针类型。*mut T:可变原始指针类型。
以上就是 Rust 中常见的数据类型,每种类型都有其特定的用途和限制。对于更复杂的数据结构,Rust 还提供了诸如枚举、结构体和 trait 等机制来支持。
FAQ?
Q1:标量类型和复合类型有什么区别?
标量类型(scalar)表示单个值,如整数、浮点数、布尔、字符;复合类型(compound)则将多个值组合在一起,如元组 (T1, T2) 和数组 [T; N]。Rust 中的标量类型默认 Copy,而复合类型只有在所有成员都 Copy 时才会自动 Copy。
Q2:&str 和 String 有什么区别?
String 是堆上分配、可变、拥有所有权的字符串类型;&str 是对字符串数据的引用(切片),不可变且不拥有所有权。&str 可以指向堆上的 String 内容,也可以指向字符串字面量(存储在二进制段中)。通常函数参数使用 &str 以兼顾两种情况。
Q3:数组和元组的区别是什么?
数组 [T; N] 要求所有元素类型相同且长度固定;元组 (T1, T2, ...) 允许不同类型,长度也固定。两者长度在编译期确定。元组常用于返回多个值,数组常用于同构集合。
Q4:Copy trait 何时会自动实现?
当类型的所有成员都实现了 Copy(如基本类型、不含堆数据的元组/数组),编译器会自动为该类型实现 Copy,赋值时按位拷贝而非移动所有权。一旦类型包含 String、Vec、Box 等拥有堆数据的类型,就不会自动 Copy,赋值时发生所有权转移。可通过 #[derive(Copy, Clone)] 显式为自定义类型实现,前提是其所有字段都已 Copy。