Skip to content

Rust 数据类型

概述

Rust 是静态类型语言,编译时必须知道所有变量的类型。本章将深入学习 Rust 的类型系统,包括标量类型、复合类型、以及类型转换等内容。

🔢 标量类型

整数类型

rust
fn integer_types() {
    // 有符号整数
    let i8_max: i8 = 127;
    let i8_min: i8 = -128;
    let i16_val: i16 = 32_767;
    let i32_val: i32 = 2_147_483_647;
    let i64_val: i64 = 9_223_372_036_854_775_807;
    let i128_val: i128 = 170_141_183_460_469_231_731_687_303_715_884_105_727;
    let isize_val: isize = 1000; // 平台相关大小
    
    println!("有符号整数: {}, {}, {}, {}, {}, {}, {}", 
             i8_max, i8_min, i16_val, i32_val, i64_val, i128_val, isize_val);
    
    // 无符号整数
    let u8_max: u8 = 255;
    let u16_max: u16 = 65_535;
    let u32_max: u32 = 4_294_967_295;
    let u64_max: u64 = 18_446_744_073_709_551_615;
    let u128_max: u128 = 340_282_366_920_938_463_463_374_607_431_768_211_455;
    let usize_val: usize = 1000; // 平台相关大小
    
    println!("无符号整数: {}, {}, {}, {}, {}, {}", 
             u8_max, u16_max, u32_max, u64_max, u128_max, usize_val);
    
    // 整数字面量的不同表示法
    let decimal = 98_222;        // 十进制
    let hex = 0xff;              // 十六进制
    let octal = 0o77;            // 八进制
    let binary = 0b1111_0000;    // 二进制
    let byte = b'A';             // 字节字面量(u8)
    
    println!("不同进制: {} {} {} {} {}", decimal, hex, octal, binary, byte);
    
    // 类型后缀
    let typed_int = 42u32;
    let another = 100_i64;
    println!("类型后缀: {}, {}", typed_int, another);
}

浮点类型

rust
fn floating_point_types() {
    // 单精度浮点
    let f32_val: f32 = 3.14159;
    let f32_scientific: f32 = 1.23e-4;
    
    // 双精度浮点(默认)
    let f64_val: f64 = 2.718281828459045;
    let default_float = 3.14; // 默认是 f64
    
    println!("浮点数: {} {} {} {}", f32_val, f32_scientific, f64_val, default_float);
    
    // 浮点数的特殊值
    let infinity = f64::INFINITY;
    let neg_infinity = f64::NEG_INFINITY;
    let nan = f64::NAN;
    
    println!("特殊值: {} {} {}", infinity, neg_infinity, nan);
    
    // 浮点数运算
    let sum = 5.0 + 10.0;
    let difference = 95.5 - 4.3;
    let product = 4.0 * 30.0;
    let quotient = 56.7 / 32.2;
    let remainder = 43.0 % 5.0;
    
    println!("运算: {} {} {} {} {}", sum, difference, product, quotient, remainder);
    
    // 浮点数比较的注意事项
    let a = 0.1 + 0.2;
    let b = 0.3;
    println!("0.1 + 0.2 = {}", a);
    println!("0.3 = {}", b);
    println!("相等吗? {}", a == b); // 可能是 false
    
    // 正确的浮点数比较
    let epsilon = f64::EPSILON;
    println!("近似相等吗? {}", (a - b).abs() < epsilon);
}

布尔类型

rust
fn boolean_type() {
    let t = true;
    let f: bool = false; // 显式类型注解
    
    println!("布尔值: {}, {}", t, f);
    
    // 布尔运算
    let and_result = t && f;   // 逻辑与
    let or_result = t || f;    // 逻辑或
    let not_result = !t;       // 逻辑非
    
    println!("逻辑运算: {} {} {}", and_result, or_result, not_result);
    
    // 短路求值
    let result1 = false && expensive_operation(); // expensive_operation 不会被调用
    let result2 = true || expensive_operation();  // expensive_operation 不会被调用
    
    println!("短路求值: {} {}", result1, result2);
    
    // 布尔到数字的转换
    let bool_as_int = t as i32;
    println!("布尔转数字: {}", bool_as_int);
}

fn expensive_operation() -> bool {
    println!("执行昂贵操作");
    true
}

字符类型

rust
fn character_type() {
    let c = 'z';
    let z = 'ℤ';
    let heart_eyed_cat = '😻';
    let chinese = '中';
    
    println!("字符: {} {} {} {}", c, z, heart_eyed_cat, chinese);
    
    // 字符字面量的不同表示
    let newline = '\n';
    let tab = '\t';
    let backslash = '\\';
    let quote = '\'';
    
    println!("转义字符: [{}] [{}] [{}] [{}]", newline, tab, backslash, quote);
    
    // ASCII 字符
    let ascii_a = '\x41'; // 'A'
    println!("ASCII: {}", ascii_a);
    
    // Unicode 字符
    let unicode_heart = '\u{2764}'; // ❤
    let unicode_emoji = '\u{1F600}'; // 😀
    println!("Unicode: {} {}", unicode_heart, unicode_emoji);
    
    // 字符相关方法
    println!("是否为字母: {}", 'a'.is_alphabetic());
    println!("是否为数字: {}", '5'.is_numeric());
    println!("是否为小写: {}", 'a'.is_lowercase());
    println!("转大写: {}", 'a'.to_uppercase().next().unwrap());
}

📦 复合类型

元组类型

rust
fn tuple_type() {
    // 基本元组
    let tup: (i32, f64, u8) = (500, 6.4, 1);
    
    // 解构元组
    let (x, y, z) = tup;
    println!("解构元组: {}, {}, {}", x, y, z);
    
    // 通过索引访问
    let first = tup.0;
    let second = tup.1;
    let third = tup.2;
    println!("索引访问: {}, {}, {}", first, second, third);
    
    // 嵌套元组
    let nested: ((i32, i32), (i32, i32)) = ((1, 2), (3, 4));
    println!("嵌套元组: {:?}", nested);
    
    // 单元素元组
    let single_element = (42,); // 注意逗号
    let not_tuple = (42);       // 这不是元组,只是括号
    println!("单元素元组: {:?}", single_element);
    
    // 空元组(单元类型)
    let unit = ();
    println!("单元类型: {:?}", unit);
    
    // 元组作为函数返回值
    let (sum, product) = calculate(4, 5);
    println!("计算结果: 和={}, 积={}", sum, product);
}

fn calculate(a: i32, b: i32) -> (i32, i32) {
    (a + b, a * b)
}

数组类型

rust
fn array_type() {
    // 基本数组
    let arr = [1, 2, 3, 4, 5];
    println!("数组: {:?}", arr);
    
    // 显式类型和长度
    let arr: [i32; 5] = [1, 2, 3, 4, 5];
    println!("类型注解数组: {:?}", arr);
    
    // 相同值初始化
    let zeros = [0; 5]; // [0, 0, 0, 0, 0]
    let threes = [3; 4]; // [3, 3, 3, 3]
    println!("初始化数组: {:?}, {:?}", zeros, threes);
    
    // 访问数组元素
    let first = arr[0];
    let second = arr[1];
    println!("数组元素: {}, {}", first, second);
    
    // 数组长度
    println!("数组长度: {}", arr.len());
    
    // 数组切片
    let slice = &arr[1..4]; // 不包含索引4
    println!("切片: {:?}", slice);
    
    // 遍历数组
    for element in arr.iter() {
        println!("元素: {}", element);
    }
    
    // 带索引遍历
    for (index, element) in arr.iter().enumerate() {
        println!("索引 {}: {}", index, element);
    }
    
    // 多维数组
    let matrix: [[i32; 3]; 2] = [[1, 2, 3], [4, 5, 6]];
    println!("矩阵: {:?}", matrix);
    println!("矩阵元素: {}", matrix[1][2]); // 6
}

🔄 类型转换

显式类型转换

rust
fn explicit_conversion() {
    // 数值类型转换
    let integer = 42i32;
    let float = integer as f64;
    let byte = integer as u8;
    
    println!("转换: {} -> {} -> {}", integer, float, byte);
    
    // 可能丢失精度的转换
    let large_number = 1000i32;
    let truncated = large_number as u8; // 可能截断
    println!("截断: {} -> {}", large_number, truncated);
    
    // 浮点到整数的转换
    let pi = 3.14f64;
    let truncated_pi = pi as i32; // 截断小数部分
    println!("浮点转整数: {} -> {}", pi, truncated_pi);
    
    // 字符到数字的转换
    let digit_char = '5';
    let digit_value = digit_char as u8; // ASCII 值
    println!("字符 '{}' 的 ASCII 值: {}", digit_char, digit_value);
    
    // 布尔到数字的转换
    let true_as_int = true as i32;
    let false_as_int = false as i32;
    println!("布尔转数字: {} -> {}, {} -> {}", true, true_as_int, false, false_as_int);
}

安全类型转换

rust
fn safe_conversion() {
    use std::convert::TryInto;
    
    // TryInto trait 提供安全转换
    let large_number: i64 = 1000;
    
    match large_number.try_into() {
        Ok(small_number) => {
            let small: i32 = small_number;
            println!("安全转换成功: {} -> {}", large_number, small);
        }
        Err(e) => println!("转换失败: {}", e),
    }
    
    // 转换可能失败的情况
    let too_large: i64 = i64::MAX;
    match too_large.try_into() {
        Ok(small_number) => {
            let small: i32 = small_number;
            println!("转换成功: {}", small);
        }
        Err(e) => println!("转换失败: {}", e),
    }
    
    // 字符串到数字的解析
    let number_string = "42";
    match number_string.parse::<i32>() {
        Ok(number) => println!("解析成功: {} -> {}", number_string, number),
        Err(e) => println!("解析失败: {}", e),
    }
    
    let invalid_string = "not_a_number";
    match invalid_string.parse::<i32>() {
        Ok(number) => println!("解析成功: {}", number),
        Err(e) => println!("解析失败: {}", e),
    }
}

🏷️ 类型别名

定义类型别名

rust
// 类型别名
type Kilometers = i32;
type Thunk = Box<dyn Fn() + Send + 'static>;

fn type_aliases() {
    // 使用类型别名
    let distance: Kilometers = 100;
    println!("距离: {} 公里", distance);
    
    // 类型别名提高可读性
    type UserId = u32;
    type UserName = String;
    type UserAge = u8;
    
    let id: UserId = 12345;
    let name: UserName = String::from("Alice");
    let age: UserAge = 30;
    
    println!("用户: ID={}, 姓名={}, 年龄={}", id, name, age);
    
    // 复杂类型的别名
    type Matrix = Vec<Vec<i32>>;
    type Point3D = (f64, f64, f64);
    type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
    
    let matrix: Matrix = vec![vec![1, 2], vec![3, 4]];
    let point: Point3D = (1.0, 2.0, 3.0);
    
    println!("矩阵: {:?}", matrix);
    println!("3D点: {:?}", point);
}

🔍 类型推断

编译器类型推断

rust
fn type_inference() {
    // 编译器可以推断类型
    let x = 42;        // i32
    let y = 3.14;      // f64
    let z = true;      // bool
    let s = "hello";   // &str
    
    println!("推断类型: {}, {}, {}, {}", x, y, z, s);
    
    // 根据使用情况推断
    let mut vec = Vec::new();
    vec.push(1); // 现在编译器知道这是 Vec<i32>
    println!("向量: {:?}", vec);
    
    // 需要类型注解的情况
    let parsed: i32 = "42".parse().expect("不是数字");
    println!("解析结果: {}", parsed);
    
    // 或者使用 turbofish 语法
    let parsed2 = "42".parse::<i32>().expect("不是数字");
    println!("Turbofish 解析: {}", parsed2);
    
    // 集合的类型推断
    let numbers = vec![1, 2, 3, 4, 5]; // Vec<i32>
    let words = vec!["hello", "world"]; // Vec<&str>
    
    println!("数字集合: {:?}", numbers);
    println!("单词集合: {:?}", words);
}

📏 类型大小和对齐

查看类型大小

rust
fn type_sizes() {
    use std::mem;
    
    // 标量类型大小
    println!("类型大小(字节):");
    println!("bool: {}", mem::size_of::<bool>());
    println!("char: {}", mem::size_of::<char>());
    println!("i8: {}", mem::size_of::<i8>());
    println!("i16: {}", mem::size_of::<i16>());
    println!("i32: {}", mem::size_of::<i32>());
    println!("i64: {}", mem::size_of::<i64>());
    println!("i128: {}", mem::size_of::<i128>());
    println!("isize: {}", mem::size_of::<isize>());
    println!("f32: {}", mem::size_of::<f32>());
    println!("f64: {}", mem::size_of::<f64>());
    
    // 复合类型大小
    println!("(i32, i32): {}", mem::size_of::<(i32, i32)>());
    println!("[i32; 5]: {}", mem::size_of::<[i32; 5]>());
    println!("&str: {}", mem::size_of::<&str>());
    println!("String: {}", mem::size_of::<String>());
    println!("Vec<i32>: {}", mem::size_of::<Vec<i32>>());
    
    // 对齐信息
    println!("\n类型对齐:");
    println!("i32 对齐: {}", mem::align_of::<i32>());
    println!("i64 对齐: {}", mem::align_of::<i64>());
    println!("(i8, i64) 对齐: {}", mem::align_of::<(i8, i64)>());
}

📝 本章小结

通过本章学习,你应该掌握了:

标量类型

  • ✅ 整数类型的范围和使用
  • ✅ 浮点类型的精度和特殊值
  • ✅ 布尔类型和字符类型
  • ✅ 字面量的不同表示法

复合类型

  • ✅ 元组的定义和使用
  • ✅ 数组的操作和遍历
  • ✅ 多维数组和切片
  • ✅ 类型推断机制

类型转换

  • ✅ 显式类型转换(as)
  • ✅ 安全类型转换(TryInto)
  • ✅ 字符串解析和错误处理
  • ✅ 类型别名的定义和使用

最佳实践

  1. 选择合适的数值类型
  2. 注意浮点数比较
  3. 使用安全的类型转换
  4. 利用类型推断简化代码

继续学习下一章 - Rust 注释

本站内容仅供学习和研究使用。