Rust 数据类型
标量类型、复合类型、字符串的两种形态、以及 `as` 转换。
Key Points`String` 是可增长的所有权字符串,`&str` 是借用的字符串切片。
标量类型
| Type | Size | Range / Note |
|---|---|---|
i8 / u8 | 1 字节 | -128~127 / 0~255 |
i32 / u32 | 4 字节 | 默认整数类型是 i32 |
i64 / u64 | 8 字节 | 时间戳、ID |
i128 / u128 | 16 字节 | 大整数 |
isize / usize | 指针宽度 | 索引、长度 |
f32 / f64 | 4 / 8 字节 | 默认浮点是 f64 |
bool | 1 字节 | true / false |
char | 4 字节 | 一个 Unicode 标量值 |
Rust
fn main() {
let i = 42; // i32
let u: u8 = 255;
let f = 3.14; // f64
let b = true;
let c = '中';
let emoji = '🦀';
println!("{} {} {} {} {} {}", i, u, f, b, c, emoji);
}Output
42 255 3.14 true 中 🦀char is a 4-byte Unicode scalar and can hold an emoji, unlike C's 1-byte char. Rust strings are not char arrays.
元组与数组
Rust
fn main() {
// 元组:可以不同类型,定长
let t: (i32, f64, char) = (1, 2.5, 'a');
let (x, y, z) = t; // 解构
println!("{} {} {}", x, y, z);
println!("{}", t.0); // 下标访问
// 数组:同类型,定长,栈上分配
let arr = [1, 2, 3, 4, 5];
let zeros = [0; 5]; // 5 个 0
println!("{} {}", arr[0], arr.len());
println!("{:?}", zeros);
// 遍历
for v in arr {
print!("{} ", v);
}
println!();
}Output
1 2.5 a
1
1 5
[0, 0, 0, 0, 0]
1 2 3 4 5 Array length is part of the type: [i32; 3] and [i32; 4] differ. Use Vec<T> day to day; arrays only for fixed small lengths.
String 与 &str
Rust
fn main() {
// &str:字符串字面量,不可变,借用
let s1: &str = "hello";
// String:堆上分配,可增长,拥有所有权
let mut s2 = String::from("hello");
s2.push_str(", world");
s2.push('!');
println!("{} | {}", s1, s2);
println!("{} {}", s1.len(), s2.len());
// String → &str
let slice: &str = &s2;
println!("{}", slice);
// &str → String
let owned: String = s1.to_string();
println!("{}", owned);
}Output
hello | hello, world!
5 13
hello, world!
hello| Type | Owns | Growable | Typical use |
|---|---|---|---|
&str | 否(借用) | 否 | 函数参数、字面量 |
String | 是 | 是 | 需要持有或修改的文本 |
Prefer
&str over String in parameters: &str accepts both &String and literals, while String forces the caller to clone. This is standard Rust advice.类型转换
Rust
fn main() {
let a = 3.99_f64;
println!("{}", a as i32); // 3,向零截断
let b = 300_i32;
println!("{}", b as u8); // 44,截断低 8 位
let c = 65_u8;
println!("{}", c as char); // A
// 字符串解析
let n: i32 = "42".parse().unwrap();
println!("{}", n + 1);
}Output
3
44
A
43as does not check: 300_i32 as u8 silently truncates to 44 and -1_i32 as u32 becomes 4294967295. For external data use TryFrom/try_into(), which return Result.Rust
use std::convert::TryInto;
let big: i64 = 300;
let small: Result<u8, _> = big.try_into();
println!("{:?}", small); // Err(PosOverflow(300))Output
Err(PosOverflow(300))标量类型
| 类型 | 大小 | 范围 / 说明 |
|---|---|---|
i8 / u8 | 1 字节 | -128~127 / 0~255 |
i32 / u32 | 4 字节 | 默认整数类型是 i32 |
i64 / u64 | 8 字节 | 时间戳、ID |
i128 / u128 | 16 字节 | 大整数 |
isize / usize | 指针宽度 | 索引、长度 |
f32 / f64 | 4 / 8 字节 | 默认浮点是 f64 |
bool | 1 字节 | true / false |
char | 4 字节 | 一个 Unicode 标量值 |
Rust
fn main() {
let i = 42; // i32
let u: u8 = 255;
let f = 3.14; // f64
let b = true;
let c = '中';
let emoji = '🦀';
println!("{} {} {} {} {} {}", i, u, f, b, c, emoji);
}Output
42 255 3.14 true 中 🦀char 是 4 字节的 Unicode 标量值,能存 emoji。这和 C 的 1 字节 char 完全不同——Rust 的字符串不是 char 数组。
元组与数组
Rust
fn main() {
// 元组:可以不同类型,定长
let t: (i32, f64, char) = (1, 2.5, 'a');
let (x, y, z) = t; // 解构
println!("{} {} {}", x, y, z);
println!("{}", t.0); // 下标访问
// 数组:同类型,定长,栈上分配
let arr = [1, 2, 3, 4, 5];
let zeros = [0; 5]; // 5 个 0
println!("{} {}", arr[0], arr.len());
println!("{:?}", zeros);
// 遍历
for v in arr {
print!("{} ", v);
}
println!();
}Output
1 2.5 a
1
1 5
[0, 0, 0, 0, 0]
1 2 3 4 5 数组长度是类型的一部分:[i32; 3] 和 [i32; 4] 是不同类型。日常用 Vec<T>(可增长),数组只在长度固定且小时用。
String 与 &str
Rust
fn main() {
// &str:字符串字面量,不可变,借用
let s1: &str = "hello";
// String:堆上分配,可增长,拥有所有权
let mut s2 = String::from("hello");
s2.push_str(", world");
s2.push('!');
println!("{} | {}", s1, s2);
println!("{} {}", s1.len(), s2.len());
// String → &str
let slice: &str = &s2;
println!("{}", slice);
// &str → String
let owned: String = s1.to_string();
println!("{}", owned);
}Output
hello | hello, world!
5 13
hello, world!
hello| 类型 | 拥有所有权 | 可增长 | 典型用途 |
|---|---|---|---|
&str | 否(借用) | 否 | 函数参数、字面量 |
String | 是 | 是 | 需要持有或修改的文本 |
函数参数写
&str 比 String 好:&str 能接受 &String 和字面量,String 只能接受 String(或调用方 .clone())。这条建议在 Rust 里叫「优先用 &str 做参数」。类型转换
Rust
fn main() {
let a = 3.99_f64;
println!("{}", a as i32); // 3,向零截断
let b = 300_i32;
println!("{}", b as u8); // 44,截断低 8 位
let c = 65_u8;
println!("{}", c as char); // A
// 字符串解析
let n: i32 = "42".parse().unwrap();
println!("{}", n + 1);
}Output
3
44
A
43as 转换不做检查:300_i32 as u8 会静默截断成 44,-1_i32 as u32 变成 4294967295。涉及外部数据时用 TryFrom / try_into(),它会返回 Result。Rust
use std::convert::TryInto;
let big: i64 = 300;
let small: Result<u8, _> = big.try_into();
println!("{:?}", small); // Err(PosOverflow(300))Output
Err(PosOverflow(300))