Rust 的基本类型主要包括以下几类:
1. 整数类型(Integer)
Rust 提供了有符号和无符号的整数类型:
- 有符号整数(
i8,i16,i32,i64,i128,isize) - 无符号整数(
u8,u16,u32,u64,u128,usize)
是否实现 Copy trait?
✅ 是的,所有整数类型都实现了 Copy,因此它们在赋值或传递时不会发生所有权转移。
存储位置:
✅ 由于整数是固定大小的标量,它们通常存储在栈上。
2. 浮点数类型(Floating-Point)
Rust 仅提供 f32 和 f64 两种浮点数类型。
是否实现 Copy trait?
✅ 是的,f32 和 f64 都实现了 Copy。
存储位置:
✅ 存储在栈上。
3. 布尔类型(Boolean)
Rust 使用 bool 类型表示布尔值(true 或 false)。
是否实现 Copy trait?
✅ 是的,bool 实现了 Copy。
存储位置:
✅ 存储在栈上。
4. 字符类型(Character)
Rust 使用 char 存储单个 Unicode 字符,占 4 字节(UTF-32)。
是否实现 Copy trait?
✅ 是的,char 实现了 Copy。
存储位置:
✅ 存储在栈上。
5. 元组(Tuple)
元组可以包含多个不同类型的数据,例如:
let tup: (i32, f64, char) = (42, 3.14, 'R');
是否实现 Copy trait?
✅ 仅当所有元素都实现了 Copy 时,元组才会自动实现 Copy。
例如:
let t1: (i32, f64) = (42, 3.14); // ✅ Copy
let t2: (String, i32) = (String::from("Hello"), 42); // ❌ 不是 Copy
存储位置:
✅ 如果所有元素都是栈上数据,元组整体存储在栈上。
❌ 如果包含堆数据(如 String),整个元组存储在栈上,但 String 的内容在堆上。
6. 数组(Array)
数组是固定长度的多个相同类型元素的集合:
let arr: [i32; 3] = [1, 2, 3];
是否实现 Copy trait?
✅ 如果元素类型实现了 Copy,数组也实现 Copy。
存储位置:
✅ 数组整体存储在栈上(因为它的大小在编译时已知)。
7. 切片(Slice)
切片是对数组的一部分的引用:
let arr = [1, 2, 3, 4, 5];
let slice: &[i32] = &arr[1..3]; // `[2, 3]`
是否实现 Copy trait?
❌ 切片本身是引用(&[T]),所以它没有 Copy,但 &T 这样的引用本身实现了 Copy。
存储位置:
✅ 切片本身存储在栈上,但它指向的数据可能在堆上或栈上。
8. String 和 &str
String是可变的、堆分配的字符串类型。&str是对String或字符串字面值的不可变引用。
是否实现 Copy trait?
❌ String 不实现 Copy(因为它在堆上)。
✅ &str 实现 Copy(因为它是引用)。
存储位置:
✅ String 本身(指针、长度、容量)存储在栈上,但字符串内容存储在堆上。
✅ &str 引用存储在栈上,指向的字符串可能在栈(字面值)或堆(String)上。
9. 结论
| 类型 | Copy 实现? | 主要存储位置 |
|---|---|---|
i32 等整数 | ✅ 是 | 栈 |
f32/f64 | ✅ 是 | 栈 |
bool | ✅ 是 | 栈 |
char | ✅ 是 | 栈 |
(i32, f64)(只包含 Copy 类型) | ✅ 是 | 栈 |
(String, i32)(包含堆数据) | ❌ 否 | 栈 + 堆 |
[i32; 3](固定大小数组) | ✅ 是 | 栈 |
[String; 3](堆数据数组) | ❌ 否 | 栈 + 堆 |
&str | ✅ 是 | 栈(但指向的可能在堆上) |
String | ❌ 否 | 栈 + 堆 |
Rust 的基本类型中,所有标量类型(整数、浮点数、布尔、字符)和只包含 Copy 类型的复合类型(元组、数组)都存储在栈上,并且都实现了 Copy。
但 String、Vec<T> 这样涉及堆数据的类型不会自动 Copy,它们的内容存储在堆上。