当前位置: 首页 > news >正文

第3章 变量与数据类型

在这里插入图片描述

文章目录

  • 第3章 变量与数据类型
    • 3.1 变量与可变性
      • 3.1.1 变量的基本概念与声明
      • 3.1.2 可变性深入解析
      • 3.1.3 变量遮蔽与重声明的区别
      • 3.1.4 常量与静态变量
      • 3.1.5 高级变量模式
    • 3.2 标量数据类型
      • 3.2.1 整数类型详解
      • 3.2.2 浮点数类型详解
      • 3.2.3 布尔类型详解
      • 3.2.4 字符类型详解
    • 3.3 复合数据类型
      • 3.3.1 元组深度解析
      • 3.3.2 数组深度解析
      • 3.3.3 结构体深度解析
      • 3.3.4 枚举深度解析
    • 3.4 类型推断与注解
      • 3.4.1 类型推断机制
      • 3.4.2 类型注解最佳实践
      • 3.4.3 类型转换与强制转换

第3章 变量与数据类型

3.1 变量与可变性

3.1.1 变量的基本概念与声明

在Rust中,变量是存储数据的基本单元,但Rust的变量系统与其他语言有着根本性的不同。让我们从基础开始,逐步深入理解Rust的变量系统。

fn variable_basics() {println!("=== 变量基础 ===");// 1. 基本变量声明 - 使用let关键字let x = 5;println!("x = {}", x);// 2. 显式类型注解let y: i32 = 10;println!("y = {}", y);// 3. 变量名可以包含Unicode字符let 姓名 = "张三";let π = 3.14159;println!("姓名: {}, π: {}", 姓名, π);// 4. 变量作用域{let inner_var = "内部变量";println!("在内部作用域: {}", inner_var);}// println!("{}", inner_var); // 错误: inner_var在这里不可见// 5. 变量遮蔽示例let shadowed = "第一次赋值";println!("遮蔽前: {}", shadowed);let shadowed = 42; // 遮蔽 - 可以改变类型println!("遮蔽后: {}", shadowed);let shadowed = shadowed * 2; // 再次遮蔽println!("再次遮蔽后: {}", shadowed);
}

3.1.2 可变性深入解析

Rust的核心特性之一就是默认不可变性。让我们深入理解这一设计选择及其影响。

fn mutability_deep_dive() {println!("\n=== 可变性深入解析 ===");// 1. 默认不可变let immutable = 100;// immutable = 200; // 编译错误: 不能给不可变变量赋值// 2. 可变变量声明let mut mutable = 100;println!("初始值: {}", mutable);mutable = 200;println!("修改后: {}", mutable);// 3. 可变性的作用域性质let mut scoped_mut = 50;{scoped_mut = 100; // 在同一个作用域内可以修改println!("内部修改: {}", scoped_mut);}println!("外部访问: {}", scoped_mut);// 4. 可变性与性能let mut large_vector = vec![0; 1_000_000];large_vector[500_000] = 1; // 需要可变性来修改元素// 5. 函数参数的可变性fn modify_value(value: &mut i32) {*value += 100;}let mut value_to_modify = 50;modify_value(&mut value_to_modify);println!("函数修改后: {}", value_to_modify);
}fn mutability_patterns() {println!("\n=== 可变性模式 ===");// 模式1: 从不可变到可变let x = 10;// let mut y = x; // 创建可变副本// y += 5;// 模式2: 重新绑定可变性let data = vec![1, 2, 3];let mut mutable_data = data; // 所有权转移,现在可变mutable_data.push(4);println!("可变数据: {:?}", mutable_data);// 模式3: 内部可变性模式(后面会详细讲解)use std::cell::Cell;let cell = Cell::new(42);cell.set(100); // 即使cell不是mut,也可以修改内部值println!("Cell内部值: {}", cell.get());
}

3.1.3 变量遮蔽与重声明的区别

理解变量遮蔽(shadowing)与重新赋值的区别至关重要。

fn shadowing_vs_reassignment() {println!("\n=== 变量遮蔽 vs 重新赋值 ===");// 1. 重新赋值(需要mut)let mut count = 0;count = 1; // 重新赋值count = 2;println!("重新赋值后的count: {}", count);// 2. 变量遮蔽let count = 0;    // 第一个countlet count = count + 1; // 遮蔽第一个countlet count = count * 2; // 再次遮蔽println!("遮蔽后的count: {}", count);// 3. 遮蔽可以改变类型let text = "123";let text: i32 = text.parse().expect("解析失败");let text = text * 2;println!("类型改变后的text: {}", text);// 4. 作用域内的遮蔽let value = "outer";println!("外部value: {}", value);{let value = 42; // 遮蔽外部valueprintln!("内部value: {}", value);} // 内部value离开作用域println!("恢复外部value: {}", value); // 外部value重新可见// 5. 模式匹配中的遮蔽let point = (10, 20);let (x, y) = point; // 解构,创建新变量x和yprintln!("点坐标: ({}, {})", x, y);// 6. 复杂的遮蔽模式let mut data = Some("hello".to_string());if let Some(text) = data { // text遮蔽了外部的dataprintln!("解构得到的text: {}", text);}// data在这里不再可用,因为所有权被移动了// println!("{:?}", data); // 编译错误
}

3.1.4 常量与静态变量

Rust提供了两种不同的全局值声明方式:常量和静态变量。

// 模块级常量
const MAX_USERS: u32 = 100_000;
const PI: f64 = 3.141592653589793;// 静态变量
static mut GLOBAL_COUNTER: u32 = 0;
static APP_NAME: &str = "MyRustApp";fn constants_and_statics() {println!("\n=== 常量与静态变量 ===");// 1. 常量使用println!("最大用户数: {}", MAX_USERS);println!("圆周率: {:.5}", PI);// 函数内常量const TIMEOUT: u32 = 30;println!("超时时间: {}秒", TIMEOUT);// 2. 静态变量使用println!("应用名称: {}", APP_NAME);// 3. 可变静态变量(不安全)unsafe {GLOBAL_COUNTER += 1;println!("全局计数器: {}", GLOBAL_COUNTER);}// 4. 常量表达式const SIZE: usize = 10;const ARRAY: [i32; SIZE] = [0; SIZE];println!("常量数组: {:?}", ARRAY);// 5. 常量函数(在编译时求值)const fn calculate_area(radius: f64) -> f64 {PI * radius * radius}const CIRCLE_AREA: f64 = calculate_area(5.0);println!("圆面积: {}", CIRCLE_AREA);
}// 关联常量
struct Math;
impl Math {const E: f64 = 2.71828;const GOLDEN_RATIO: f64 = 1.61803;
}fn associated_constants() {println!("\n=== 关联常量 ===");println!("自然常数 e: {}", Math::E);println!("黄金比例: {}", Math::GOLDEN_RATIO);
}

3.1.5 高级变量模式

让我们探索一些高级的变量使用模式。

fn advanced_variable_patterns() {println!("\n=== 高级变量模式 ===");// 1. 解构元组let point = (10, 20, 30);let (x, y, z) = point;println!("三维点: ({}, {}, {})", x, y, z);// 2. 解构时忽略某些值let (first, _, third) = point;println!("第一个和第三个值: {}, {}", first, third);// 3. 解构结构体struct Point { x: i32, y: i32, z: i32 }let point = Point { x: 1, y: 2, z: 3 };let Point { x, y: renamed_y, z } = point;println!("结构体解构: x={}, y={}, z={}", x, renamed_y, z);// 4. 模式匹配中的变量绑定let number = Some(42);if let Some(n @ 1..=100) = number {println!("数字在1-100范围内: {}", n);}// 5. 变量在闭包中的捕获let base = 10;let adder = |x| x + base; // 闭包捕获baseprintln!("闭包计算结果: {}", adder(5));// 6. 变量与生命周期let string1 = String::from("长生命周期");let result;{let string2 = String::from("短生命周期");result = longest_string(&string1, &string2);println!("较长的字符串: {}", result);}// result在这里仍然可用,因为它引用的是string1// 7. 变量与泛型let generic_var: Vec<Box<dyn std::fmt::Display>> = vec![Box::new(42),Box::new("hello"),Box::new(3.14),];for item in generic_var {println!("泛型项: {}", item);}
}fn longest_string<'a>(s1: &'a str, s2: &'a str) -> &'a str {if s1.len() > s2.len() { s1 } else { s2 }
}

3.2 标量数据类型

3.2.1 整数类型详解

Rust提供了多种整数类型,每种都有明确的大小和符号性质。

fn integer_types_deep_dive() {println!("=== 整数类型详解 ===");// 1. 有符号整数let i8_val: i8 = 127;let i16_val: i16 = 32767;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;println!("i8 最大值: {}", i8_val);println!("i16最大值: {}", i16_val);println!("i32最大值: {}", i32_val);println!("i64最大值: {}", i64_val);println!("i128最大值: {}", i128_val);// 2. 无符号整数let u8_val: u8 = 255;let u16_val: u16 = 65535;let u32_val: u32 = 4_294_967_295;let u64_val: u64 = 18_446_744_073_709_551_615;let u128_val: u128 = 340_282_366_920_938_463_463_374_607_431_768_211_455;println!("u8 最大值: {}", u8_val);println!("u16最大值: {}", u16_val);println!("u32最大值: {}", u32_val);println!("u64最大值: {}", u64_val);println!("u128最大值: {}", u128_val);// 3. 平台相关整数let isize_val: isize = -1;let usize_val: usize = 1;println!("isize: {}, usize: {}", isize_val, usize_val);println!("指针大小: {}字节", std::mem::size_of::<usize>());// 4. 整数字面量let decimal = 98_222;let hex = 0xff;let octal = 0o77;let binary = 0b1111_0000;let byte = b'A'; // u8println!("十进制: {}", decimal);println!("十六进制: 0x{:x} -> {}", hex, hex);println!("八进制: 0o{:o} -> {}", octal, octal);println!("二进制: 0b{:b} -> {}", binary, binary);println!("字节: b'{}' -> {}", byte as char, byte);// 5. 整数运算let a = 10;let b = 3;println!("加法: {} + {} = {}", a, b, a + b);println!("减法: {} - {} = {}", a, b, a - b);println!("乘法: {} * {} = {}", a, b, a * b);println!("除法: {} / {} = {}", a, b, a / b);println!("取余: {} % {} = {}", a, b, a % b);// 6. 溢出处理let mut counter: u8 = 255;// counter += 1; // 调试模式会panic,发布模式会环绕// 安全的溢出操作let (result, overflowed) = counter.overflowing_add(1);println!("溢出加法: {} (溢出: {})", result, overflowed);// 7. 整数方法let number = 42i32;println!("42的二进制: {:b}", number);println!("42转字符串: {}", number.to_string());println!("字符串转整数: {}", "123".parse::<i32>().unwrap());// 8. 字节序处理let value: u32 = 0x12345678;println!("原始值: 0x{:x}", value);println!("大端序: 0x{:x}", value.to_be());println!("小端序: 0x{:x}", value.to_le());println!("本地端序: 0x{:x}", value.to_ne_bytes().iter().fold(0, |acc, &b| (acc << 8) | b as u32));
}

3.2.2 浮点数类型详解

Rust提供两种浮点数类型:f32和f64。

fn floating_point_deep_dive() {println!("\n=== 浮点数类型详解 ===");// 1. 基本浮点数类型let f32_val: f32 = 3.14159;let f64_val: f64 = 3.141592653589793;println!("f32精度: {:.10}", f32_val);println!("f64精度: {:.15}", f64_val);// 2. 浮点数表示let scientific = 6.022e23; // 阿伏伽德罗常数let negative = -1.602e-19; // 电子电荷println!("科学计数法: {}", scientific);println!("负指数: {}", negative);// 3. 特殊浮点数值let infinity = f64::INFINITY;let neg_infinity = f64::NEG_INFINITY;let nan = f64::NAN;println!("正无穷: {}", infinity);println!("负无穷: {}", neg_infinity);println!("非数字: {}", nan);println!("NaN检查: {}", nan.is_nan());// 4. 浮点数运算let x = 10.5;let y = 3.2;println!("基本运算:");println!("  {} + {} = {:.2}", x, y, x + y);println!("  {} - {} = {:.2}", x, y, x - y);println!("  {} * {} = {:.2}", x, y, x * y);println!("  {} / {} = {:.2}", x, y, x / y);println!("  {} % {} = {:.2}", x, y, x % y);// 5. 数学函数println!("\n数学函数:");println!("  平方根: {:.2}", x.sqrt());println!("  自然对数: {:.2}", x.ln());println!("  常用对数: {:.2}", x.log10());println!("  指数函数: {:.2}", x.exp());println!("  正弦: {:.2}", x.sin());println!("  余弦: {:.2}", x.cos());println!("  正切: {:.2}", x.tan());// 6. 浮点数比较的注意事项let a = 0.1 + 0.2;let b = 0.3;println!("\n浮点数比较:");println!("  0.1 + 0.2 = {:.17}", a);println!("  0.3       = {:.17}", b);println!("  直接比较: {}", a == b);println!("  容差比较: {}", (a - b).abs() < f64::EPSILON);// 7. 取整方法let num = 3.75;println!("\n取整操作:");println!("  向下取整: {}", num.floor());println!("  向上取整: {}", num.ceil());println!("  四舍五入: {}", num.round());println!("  截断小数: {}", num.trunc());println!("  小数部分: {}", num.fract());// 8. 最大值和最小值println!("\n极值:");println!("  f32最大值: {}", f32::MAX);println!("  f32最小值: {}", f32::MIN);println!("  f64最大值: {}", f64::MAX);println!("  f64最小值: {}", f64::MIN);println!("  f32最小正数: {}", f32::MIN_POSITIVE);// 9. 精度控制let precise_number = 123.456789;println!("\n精度控制:");println!("  默认: {}", precise_number);println!("  2位小数: {:.2}", precise_number);println!("  科学计数法: {:e}", precise_number);println!("  十六进制: {:x}", precise_number.to_bits());
}

3.2.3 布尔类型详解

布尔类型虽然简单,但在Rust中有一些重要的特性和用法。

fn boolean_type_deep_dive() {println!("\n=== 布尔类型详解 ===");// 1. 基本布尔值let true_val = true;let false_val = false;println!("真: {}, 假: {}", true_val, false_val);// 2. 布尔运算println!("\n布尔运算:");println!("  true AND false: {}", true_val && false_val);println!("  true OR false: {}", true_val || false_val);println!("  NOT true: {}", !true_val);println!("  XOR: {}", true_val ^ false_val);// 3. 布尔值在条件表达式中的使用let number = 42;let is_even = number % 2 == 0;let is_positive = number > 0;println!("\n条件检查:");println!("  {}是偶数: {}", number, is_even);println!("  {}是正数: {}", number, is_positive);// 4. 布尔值的转换println!("\n类型转换:");println!("  true as i32: {}", true as i32);println!("  false as i32: {}", false as i32);// 5. 布尔值在模式匹配中的应用let option_val: Option<i32> = Some(42);if let Some(value) = option_val {println!("Option包含值: {}", value);} else {println!("Option为空");}// 6. 短路求值println!("\n短路求值演示:");fn expensive_check() -> bool {println!("执行昂贵检查...");true}let short_circuit = false && expensive_check(); // expensive_check不会被调用println!("短路与结果: {}", short_circuit);let short_circuit_or = true || expensive_check(); // expensive_check不会被调用println!("短路或结果: {}", short_circuit_or);// 7. 布尔值在集合操作中的应用let numbers = vec![1, 2, 3, 4, 5];let even_numbers: Vec<i32> = numbers.iter().filter(|&&x| x % 2 == 0) // 过滤函数返回布尔值.cloned().collect();println!("偶数: {:?}", even_numbers);// 8. 布尔值的位运算let flags = 0b1010u8; // 二进制标志位let has_second_bit = (flags & 0b0010) != 0;let has_third_bit = (flags & 0b0100) != 0;println!("标志位: {:08b}", flags);println!("第二位设置: {}", has_second_bit);println!("第三位设置: {}", has_third_bit);// 9. 布尔代数定律验证println!("\n布尔代数验证:");let a = true;let b = false;// 同一律println!("同一律 - a AND true: {}", a && true);println!("同一律 - a OR false: {}", a || false);// 零律println!("零律 - a AND false: {}", a && false);println!("零律 - a OR true: {}", a || true);// 排中律println!("排中律 - a OR NOT a: {}", a || !a);// 矛盾律println!("矛盾律 - a AND NOT a: {}", a && !a);
}

3.2.4 字符类型详解

Rust的char类型是Unicode标量值,支持完整的Unicode字符集。

fn character_type_deep_dive() {println!("\n=== 字符类型详解 ===");// 1. 基本字符let ascii_char = 'A';let digit_char = '9';let symbol_char = '$';let space_char = ' ';println!("ASCII字符: '{}'", ascii_char);println!("数字字符: '{}'", digit_char);println!("符号字符: '{}'", symbol_char);println!("空格字符: '{}'", space_char);// 2. Unicode字符let chinese_char = '中';let japanese_char = 'こ';let emoji_char = '🚀';let math_symbol = '∑';println!("中文: '{}'", chinese_char);println!("日文: '{}'", japanese_char);println!("表情: '{}'", emoji_char);println!("数学符号: '{}'", math_symbol);// 3. 转义字符println!("\n转义字符:");println!("  换行: '\\n' -> {}", "line1\nline2");println!("  制表符: '\\t' -> {}", "col1\tcol2");println!("  回车: '\\r'");println!("  反斜杠: '\\\\' -> \\");println!("  单引号: '\\'' -> '");println!("  双引号: '\\\"' -> \"");// 4. 原始字符串字面量let raw_string = r#"这是一个"原始"字符串\不需要转义\n"#;println!("原始字符串: {}", raw_string);// 5. 字符编码相关println!("\n字符编码信息:");let sample_char = 'A';println!("  字符 '{}' 的Unicode标量值: U+{:04X}", sample_char, sample_char as u32);println!("  占用字节数: {}", std::mem::size_of::<char>());// 6. 字符分类方法let test_chars = ['A', '9', ' ', '中', '🚀'];for &ch in &test_chars {println!("字符 '{}':", ch);println!("  是字母数字: {}", ch.is_alphabetic() || ch.is_numeric());println!("  是字母: {}", ch.is_alphabetic());println!("  是数字: {}", ch.is_numeric());println!("  是空白: {}", ch.is_whitespace());println!("  是控制字符: {}", ch.is_control());println!("  是小写: {}", ch.is_lowercase());println!("  是大写: {}", ch.is_uppercase());}// 7. 字符转换println!("\n字符转换:");let upper_a = 'A';let lower_a = upper_a.to_ascii_lowercase();println!("  大写转小写: '{}' -> '{}'", upper_a, lower_a);let digit_char = '5';let digit_value = digit_char.to_digit(10).unwrap();println!("  字符转数字: '{}' -> {}", digit_char, digit_value);// 8. 字符迭代let text = "Hello 世界 🚀";println!("\n字符迭代 '{}':", text);for (i, ch) in text.chars().enumerate() {println!("  位置 {}: '{}' (U+{:04X})", i, ch, ch as u32);}// 9. 字节与字符的区别let multi_byte = "🦀";println!("\n多字节字符 '{}':", multi_byte);println!("  字符数: {}", multi_byte.chars().count());println!("  字节数: {}", multi_byte.len());for byte in multi_byte.bytes() {println!("  字节: 0x{:02X}", byte);}// 10. 字符字面量的各种形式println!("\n字符字面量形式:");let char_hex = '\x41';        // 十六进制let char_unicode = '\u{41}';  // Unicodelet char_unicode_chinese = '\u{4E2D}'; // 中文"中"let char_unicode_emoji = '\u{1F680}'; // 火箭表情println!("  十六进制: \\x41 -> '{}'", char_hex);println!("  Unicode: \\u{{41}} -> '{}'", char_unicode);println!("  Unicode中文: \\u{{4E2D}} -> '{}'", char_unicode_chinese);println!("  Unicode表情: \\u{{1F680}} -> '{}'", char_unicode_emoji);
}

3.3 复合数据类型

3.3.1 元组深度解析

元组是将多个不同类型的值组合成一个复合类型的通用方式。

fn tuple_deep_dive() {println!("=== 元组深度解析 ===");// 1. 基本元组let basic_tuple = (1, "hello", 3.14, true);println!("基本元组: {:?}", basic_tuple);// 2. 类型注解let typed_tuple: (i32, f64, char) = (42, 3.14159, 'A');println!("带类型注解的元组: {:?}", typed_tuple);// 3. 单元素元组(需要逗号)let single_element = (42,);println!("单元素元组: {:?}", single_element);// 4. 空元组(单元类型)let empty_tuple = ();println!("空元组: {:?}", empty_tuple);// 5. 访问元组元素let person = ("Alice", 30, 165.5);println!("访问元素:");println!("  姓名: {}", person.0);println!("  年龄: {}", person.1);println!("  身高: {}", person.2);// 6. 元组解构let (name, age, height) = person;println!("解构结果: {}, {}, {}", name, age, height);// 7. 解构时忽略某些元素let (name, _, height) = person;println!("部分解构: {}, {}", name, height);// 8. 嵌套元组let nested_tuple = (1, ("inner", 2.5), 3);println!("嵌套元组: {:?}", nested_tuple);let (first, (inner_str, inner_float), third) = nested_tuple;println!("嵌套解构: {}, {}, {}, {}", first, inner_str, inner_float, third);// 9. 元组比较let tuple1 = (1, "hello");let tuple2 = (1, "hello");let tuple3 = (2, "world");println!("元组比较:");println!("  tuple1 == tuple2: {}", tuple1 == tuple2);println!("  tuple1 == tuple3: {}", tuple1 == tuple3);println!("  tuple1 < tuple3: {}", tuple1 < tuple3);// 10. 元组作为函数参数和返回值fn swap<T, U>(pair: (T, U)) -> (U, T) {(pair.1, pair.0)}let original = (1, "hello");let swapped = swap(original);println!("交换前: {:?}", original);println!("交换后: {:?}", swapped);// 11. 元组在模式匹配中的应用let point = (0, 5);match point {(0, 0) => println!("在原点"),(0, y) => println!("在Y轴上,y = {}", y),(x, 0) => println!("在X轴上,x = {}", x),(x, y) => println!("在点 ({}, {})", x, y),}// 12. 元组的方法let mut mutable_tuple = (1, 2, 3);println!("可变元组: {:?}", mutable_tuple);mutable_tuple.0 = 10;println!("修改后: {:?}", mutable_tuple);// 13. 元组与索引let data = (100, "text", vec![1, 2, 3]);// 使用常量索引const IDX: usize = 0;println!("使用常量索引: {}", data.IDX);// 14. 元组的Debug和Display#[derive(Debug)]struct Point2D { x: i32, y: i32 }let point_tuple = (Point2D { x: 1, y: 2 }, Point2D { x: 3, y: 4 });println!("结构体元组: {:?}", point_tuple);// 15. 最大元组长度// Rust支持最多12个元素的元组用于各种trait实现let large_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);println!("12元素元组: {:?}", large_tuple);
}

3.3.2 数组深度解析

数组是包含多个相同类型元素的固定大小集合。

fn array_deep_dive() {println!("\n=== 数组深度解析 ===");// 1. 数组声明方式let array1 = [1, 2, 3, 4, 5];let array2: [i32; 5] = [1, 2, 3, 4, 5];let array3 = [0; 5]; // 5个元素,都是0println!("数组1: {:?}", array1);println!("数组2: {:?}", array2);println!("数组3: {:?}", array3);// 2. 访问数组元素println!("访问元素:");println!("  第一个元素: {}", array1[0]);println!("  最后一个元素: {}", array1[array1.len() - 1]);// 3. 数组切片let slice = &array1[1..4];println!("切片 [1..4]: {:?}", slice);// 4. 数组迭代println!("数组迭代:");for (index, &value) in array1.iter().enumerate() {println!("  [{}] = {}", index, value);}// 5. 数组映射let doubled: Vec<i32> = array1.iter().map(|&x| x * 2).collect();println!("加倍后: {:?}", doubled);// 6. 多维数组let matrix: [[i32; 3]; 3] = [[1, 2, 3],[4, 5, 6],[7, 8, 9],];println!("二维数组:");for row in &matrix {println!("  {:?}", row);}// 7. 数组比较let arr1 = [1, 2, 3];let arr2 = [1, 2, 3];let arr3 = [4, 5, 6];println!("数组比较:");println!("  arr1 == arr2: {}", arr1 == arr2);println!("  arr1 == arr3: {}", arr1 == arr3);// 8. 数组方法println!("数组方法:");println!("  长度: {}", array1.len());println!("  是否为空: {}", array1.is_empty());println!("  第一个元素: {:?}", array1.first());println!("  最后一个元素: {:?}", array1.last());// 9. 数组排序let mut unsorted = [3, 1, 4, 1, 5, 9, 2];unsorted.sort();println!("排序后: {:?}", unsorted);// 10. 数组搜索let numbers = [10, 20, 30, 40, 50];if let Some(index) = numbers.iter().position(|&x| x == 30) {println!("找到30在位置: {}", index);}// 11. 数组与模式匹配let point = [0, 5];match point {[0, 0] => println!("在原点"),[0, y] => println!("在Y轴上,y = {}", y),[x, 0] => println!("在X轴上,x = {}", x),[x, y] => println!("在点 ({}, {})", x, y),}// 12. 数组常量const CONST_ARRAY: [i32; 3] = [1, 2, 3];println!("常量数组: {:?}", CONST_ARRAY);// 13. 数组与向量转换let array = [1, 2, 3];let vector = array.to_vec();let back_to_array: [i32; 3] = vector.try_into().unwrap();println!("数组转向量: {:?}", vector);println!("向量转数组: {:?}", back_to_array);// 14. 数组的get方法(安全访问)let safe_access = array1.get(2);let out_of_bounds = array1.get(10);println!("安全访问:");println!("  索引2: {:?}", safe_access);println!("  索引10: {:?}", out_of_bounds);// 15. 数组的windows和chunkslet data = [1, 2, 3, 4, 5];println!("滑动窗口:");for window in data.windows(3) {println!("  {:?}", window);}println!("分块:");for chunk in data.chunks(2) {println!("  {:?}", chunk);}// 16. 零大小数组let empty_array: [i32; 0] = [];println!("空数组: {:?}", empty_array);println!("空数组长度: {}", empty_array.len());
}

3.3.3 结构体深度解析

结构体是创建自定义数据类型的主要方式。

fn struct_deep_dive() {println!("\n=== 结构体深度解析 ===");// 1. 基本结构体定义#[derive(Debug, Clone)]struct Person {name: String,age: u32,height: f64,}// 2. 结构体实例化let person1 = Person {name: String::from("Alice"),age: 30,height: 165.5,};println!("Person1: {:?}", person1);// 3. 字段初始化简写let name = String::from("Bob");let age = 25;let height = 180.0;let person2 = Person { name, age, height };println!("Person2: {:?}", person2);// 4. 结构体更新语法let person3 = Person {name: String::from("Charlie"),..person1 // 使用person1的其他字段};println!("Person3: {:?}", person3);// 5. 元组结构体struct Color(u8, u8, u8);struct Point(f64, f64);let red = Color(255, 0, 0);let origin = Point(0.0, 0.0);println!("红色: ({}, {}, {})", red.0, red.1, red.2);println!("原点: ({}, {})", origin.0, origin.1);// 6. 单元结构体struct Marker;let marker = Marker;println!("单元结构体: {:?}", marker);// 7. 结构体方法impl Person {// 关联函数(静态方法)fn new(name: String, age: u32, height: f64) -> Self {Self { name, age, height }}// 实例方法fn introduce(&self) -> String {format!("我叫{},今年{}岁,身高{}cm", self.name, self.age, self.height)}// 可变方法fn have_birthday(&mut self) {self.age += 1;}// 获取方法fn is_adult(&self) -> bool {self.age >= 18}}let mut person4 = Person::new(String::from("David"), 17, 175.0);println!("介绍: {}", person4.introduce());println!("是成年人: {}", person4.is_adult());person4.have_birthday();println!("生日后: {}", person4.introduce());println!("是成年人: {}", person4.is_adult());// 8. 结构体模式匹配match person4 {Person { age: 18, .. } => println!("刚好18岁!"),Person { age, .. } if age < 18 => println!("还是未成年人"),Person { age, .. } if age > 18 => println!("已经是成年人"),_ => (),}// 9. 结构体与trait#[derive(PartialEq, Eq, Hash)]struct UserId(u64);let id1 = UserId(123);let id2 = UserId(123);println!("ID相等: {}", id1 == id2);// 10. 结构体默认值#[derive(Default, Debug)]struct Settings {volume: u8,brightness: u8,language: String,}let default_settings = Settings::default();println!("默认设置: {:?}", default_settings);let custom_settings = Settings {volume: 80,..Settings::default()};println!("自定义设置: {:?}", custom_settings);// 11. 结构体与生命周期#[derive(Debug)]struct Name<'a> {first: &'a str,last: &'a str,}let first_name = "John";let last_name = "Doe";let name = Name {first: first_name,last: last_name,};println!("姓名: {:?}", name);// 12. 泛型结构体#[derive(Debug)]struct Pair<T, U> {first: T,second: U,}let int_pair = Pair { first: 1, second: 2 };let mixed_pair = Pair { first: "hello", second: 3.14 };println!("整数对: {:?}", int_pair);println!("混合对: {:?}", mixed_pair);// 13. 结构体大小和对齐println!("\n结构体大小信息:");println!("  Person大小: {}字节", std::mem::size_of::<Person>());println!("  Color大小: {}字节", std::mem::size_of::<Color>());println!("  Marker大小: {}字节", std::mem::size_of::<Marker>());// 14. 结构体与内存布局#[repr(C)]struct CLikeStruct {x: i32,y: i32,}let c_struct = CLikeStruct { x: 10, y: 20 };println!("C风格结构体: x={}, y={}", c_struct.x, c_struct.y);
}

3.3.4 枚举深度解析

枚举是Rust中强大的数据类型,可以表示多种可能的值。

fn enum_deep_dive() {println!("\n=== 枚举深度解析 ===");// 1. 基本枚举#[derive(Debug)]enum IpAddrKind {V4,V6,}let four = IpAddrKind::V4;let six = IpAddrKind::V6;println!("IP类型: {:?}, {:?}", four, six);// 2. 带数据的枚举#[derive(Debug)]enum IpAddr {V4(u8, u8, u8, u8),V6(String),}let home = IpAddr::V4(127, 0, 0, 1);let loopback = IpAddr::V6(String::from("::1"));println!("IP地址: {:?}", home);println!("回环地址: {:?}", loopback);// 3. 结构体风格的枚举变体#[derive(Debug)]enum Message {Quit,Move { x: i32, y: i32 },Write(String),ChangeColor(i32, i32, i32),}let messages = [Message::Quit,Message::Move { x: 10, y: 20 },Message::Write(String::from("hello")),Message::ChangeColor(255, 0, 0),];for msg in &messages {println!("消息: {:?}", msg);}// 4. 枚举方法impl Message {fn call(&self) {match self {Message::Quit => println!("退出消息"),Message::Move { x, y } => println!("移动到 ({}, {})", x, y),Message::Write(text) => println!("写入: {}", text),Message::ChangeColor(r, g, b) => println!("改变颜色: ({}, {}, {})", r, g, b),}}}println!("\n调用枚举方法:");for msg in &messages {msg.call();}// 5. Option枚举let some_number = Some(5);let no_number: Option<i32> = None;println!("\nOption枚举:");println!("  有值: {:?}", some_number);println!("  无值: {:?}", no_number);// 6. Result枚举fn divide(a: f64, b: f64) -> Result<f64, String> {if b == 0.0 {Err("除数不能为零".to_string())} else {Ok(a / b)}}println!("\nResult枚举:");println!("  成功: {:?}", divide(10.0, 2.0));println!("  失败: {:?}", divide(10.0, 0.0));// 7. 模式匹配与枚举fn process_message(msg: Message) {match msg {Message::Quit => println!("处理退出"),Message::Move { x, y } => println!("处理移动到 ({}, {})", x, y),Message::Write(text) => println!("处理写入: {}", text),Message::ChangeColor(r, g, b) => println!("处理颜色改变"),}}println!("\n模式匹配处理:");for msg in messages {process_message(msg);}// 8. if let 简洁语法let some_value = Some(42);if let Some(x) = some_value {println!("if let 得到值: {}", x);}// 9. 枚举与内存优化println!("\n枚举内存优化:");println!("  Option<bool> 大小: {}字节", std::mem::size_of::<Option<bool>>());println!("  Option<Box<i32>> 大小: {}字节", std::mem::size_of::<Option<Box<i32>>>());// 10. 递归枚举#[derive(Debug)]enum List {Cons(i32, Box<List>),Nil,}let list = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));println!("递归枚举列表: {:?}", list);// 11. 枚举与trait绑定trait Display {fn display(&self);}impl Display for Message {fn display(&self) {match self {Message::Quit => println!("显示: 退出"),Message::Move { x, y } => println!("显示: 移动到 ({}, {})", x, y),Message::Write(text) => println!("显示: 写入 {}", text),Message::ChangeColor(r, g, b) => println!("显示: 颜色 ({}, {}, {})", r, g, b),}}}println!("\n枚举trait实现:");let write_msg = Message::Write(String::from("hello world"));write_msg.display();// 12. 枚举的Clone和Copy#[derive(Debug, Clone, Copy)]enum SimpleEnum {A,B(i32),}let simple = SimpleEnum::B(42);let copied = simple;println!("可复制的枚举: {:?}, {:?}", simple, copied);
}

3.4 类型推断与注解

3.4.1 类型推断机制

Rust拥有强大的类型推断系统,能够在大多数情况下自动推断出变量的类型。

fn type_inference_mechanism() {println!("=== 类型推断机制 ===");// 1. 基础类型推断let x = 5;        // 推断为 i32let y = 3.14;     // 推断为 f64let z = true;     // 推断为 boollet s = "hello";  // 推断为 &strprintln!("基础推断: x={} (i32), y={} (f64), z={} (bool), s={} (&str)", x, y, z, s);// 2. 从使用上下文推断let mut vec = Vec::new(); // 无法推断具体类型vec.push(1);              // 现在推断为 Vec<i32>vec.push(2);println!("从使用推断: {:?}", vec);// 3. 函数返回类型推断fn identity(x: i32) -> i32 { x } // 返回类型明确fn parse_number(s: &str) -> Result<i32, _> {s.parse() // 从parse()的返回类型推断}// 4. 闭包类型推断let closure = |x| x + 1; // 输入输出类型从使用处推断let result = closure(5);println!("闭包推断: {}", result);// 5. 泛型类型推断let numbers: Vec<_> = (0..5).collect(); // 从范围推断为 Vec<i32>println!("泛型推断: {:?}", numbers);// 6. 模式匹配中的类型推断let tuple = (1, "hello", 3.14);let (a, b, c) = tuple; // a: i32, b: &str, c: f64println!("模式匹配推断: {}, {}, {}", a, b, c);// 7. 循环中的类型推断let array = [1, 2, 3, 4, 5];for element in &array {// element 被推断为 &i32println!("循环推断: {}", element);}// 8. 方法调用链的类型推断let processed: Vec<String> = array.iter().map(|x| x.to_string())    // x 推断为 &i32.filter(|s| s.len() == 1)  // s 推断为 &String.collect();                // 从左侧类型注解推断println!("方法链推断: {:?}", processed);// 9. 条件表达式中的类型推断let condition = true;let value = if condition { 42 } else { 100 }; // 推断为 i32println!("条件推断: {}", value);// 10. 结构体更新语法中的推断#[derive(Debug)]struct Config {host: String,port: u16,timeout: u32,}let base_config = Config {host: "localhost".to_string(),port: 8080,timeout: 30,};let new_config = Config {host: "127.0.0.1".to_string(),..base_config // 推断其他字段类型};println!("结构体更新推断: {:?}", new_config);
}fn type_inference_limits() {println!("\n=== 类型推断的局限性 ===");// 1. 歧义类型需要注解// let number = "42".parse().unwrap(); // 错误: 无法推断类型let number: i32 = "42".parse().unwrap(); // 需要类型注解println!("需要注解: {}", number);// 2. 空集合需要类型提示// let empty_vec = Vec::new(); // 错误: 无法推断元素类型let empty_vec: Vec<String> = Vec::new();let empty_vec2 = Vec::<i32>::new(); // turbofish语法println!("空向量: {:?}, {:?}", empty_vec, empty_vec2);// 3. 闭包参数需要类型提示的情况// let closure = |x| x; // 错误: 无法推断类型let closure = |x: i32| x;println!("闭包需要注解: {}", closure(42));// 4. 多个可能类型的情况let collection: Vec<Box<dyn std::fmt::Debug>> = vec![Box::new(42),Box::new("hello"),];println!("多态集合: {:?}", collection);// 5. 递归数据结构需要类型注解#[derive(Debug)]enum List<T> {Cons(T, Box<List<T>>),Nil,}// 必须明确指定T的类型let list: List<i32> = List::Cons(1, Box::new(List::Nil));println!("递归结构: {:?}", list);
}

3.4.2 类型注解最佳实践

了解何时以及如何使用类型注解。

fn type_annotation_best_practices() {println!("=== 类型注解最佳实践 ===");// 1. 函数签名必须注解fn add(x: i32, y: i32) -> i32 {x + y}println!("函数注解: {} + {} = {}", 5, 3, add(5, 3));// 2. 复杂类型建议注解let complex: std::collections::HashMap<String, Vec<usize>> = std::collections::HashMap::new();println!("复杂类型注解: {:?}", complex);// 3. 提高代码可读性let timeout: u32 = 30; // 明确表示这是超时时间let port: u16 = 8080;  // 明确端口类型println!("提高可读性: timeout={}, port={}", timeout, port);// 4. 文档中的类型注解/// 计算圆的面积/// /// # 参数/// /// * `radius` - 圆的半径 (f64)/// /// # 返回值/// /// 圆的面积 (f64)fn circle_area(radius: f64) -> f64 {std::f64::consts::PI * radius * radius}let area = circle_area(5.0);println!("文档注解: 面积 = {:.2}", area);// 5. 错误处理中的类型注解fn parse_config(config_str: &str) -> Result<Config, Box<dyn std::error::Error>> {// 复杂的错误类型需要注解Ok(Config {host: "localhost".to_string(),port: 8080,timeout: 30,})}// 6. 泛型约束注解fn display<T: std::fmt::Display>(value: T) {println!("显示: {}", value);}display(42);display("hello");// 7. 生命周期注解fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {if s1.len() > s2.len() { s1 } else { s2 }}let s1 = "hello";let s2 = "world";println!("生命周期注解: {}", longest(s1, s2));// 8. 类型别名type UserId = u64;type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;let user_id: UserId = 12345;println!("类型别名: {}", user_id);
}fn advanced_type_patterns() {println!("\n=== 高级类型模式 ===");// 1. 新类型模式struct UserId(u64);struct ProductId(u64);let user = UserId(123);let product = ProductId(123);// println!("{}", user == product); // 错误: 类型不匹配println!("新类型模式: UserId({}), ProductId({})", user.0, product.0);// 2. 类型状态模式struct Unvalidated;struct Validated;struct Data<S> {value: String,state: std::marker::PhantomData<S>,}impl Data<Unvalidated> {fn validate(self) -> Result<Data<Validated>, String> {if self.value.is_empty() {Err("数据不能为空".to_string())} else {Ok(Data {value: self.value,state: std::marker::PhantomData,})}}}let unvalidated = Data::<Unvalidated> {value: "hello".to_string(),state: std::marker::PhantomData,};match unvalidated.validate() {Ok(validated) => println!("验证成功"),Err(e) => println!("验证失败: {}", e),}// 3. 零大小类型struct Nothing;let nothing = Nothing;println!("零大小类型大小: {}字节", std::mem::size_of::<Nothing>());// 4. 动态大小类型let trait_object: &dyn std::fmt::Debug = &42;println!("动态大小类型: {:?}", trait_object);// 5. 关联类型trait Container {type Item;fn get_item(&self) -> &Self::Item;}struct MyContainer<T> {item: T,}impl<T> Container for MyContainer<T> {type Item = T;fn get_item(&self) -> &Self::Item {&self.item}}let container = MyContainer { item: 42 };println!("关联类型: {}", container.get_item());
}

3.4.3 类型转换与强制转换

理解Rust中的类型转换机制。

fn type_conversion_and_coercion() {println!("=== 类型转换与强制转换 ===");// 1. 显式类型转换 (as)let x = 42i32;let y = x as i64;let z = x as f64;println!("显式转换: i32 {} -> i64 {} -> f64 {}", x, y, z);// 2. 数值类型转换let int_val = 255u8;let int_to_float = int_val as f32;let float_to_int = 3.14 as i32; // 截断println!("数值转换: u8 {} -> f32 {} -> i32 {}", int_val, int_to_float, float_to_int);// 3. 指针类型转换let number = 42;let raw_ptr = &number as *const i32;println!("指针转换: {:p}", raw_ptr);// 4. 强制类型转换fn take_string_slice(s: &str) {println!("字符串切片: {}", s);}let string_literal = "hello";let string_object = String::from("world");take_string_slice(string_literal);           // &str -> &strtake_string_slice(&string_object);           // &String -> &str (强制转换)// 5. From 和 Into traitlet number = 42;let number_string = String::from("42");let parsed: i32 = number_string.parse().unwrap();let back_to_string = parsed.to_string();println!("From/Into: {} -> {} -> {}", number, parsed, back_to_string);// 6. TryFrom 和 TryInto (安全转换)use std::convert::TryFrom;let large_number = 1000i32;let small: Result<u8, _> = large_number.try_into();match small {Ok(value) => println!("成功转换: {}", value),Err(_) => println!("转换失败: 值太大"),}// 7. 引用强制转换fn process<T: std::fmt::Display>(value: &T) {println!("处理: {}", value);}let value = 42;process(&value);        // &i32 -> &i32process(&&value);       // &&i32 -> &i32 (解引用强制转换)process(&&&value);      // &&&i32 -> &i32 (多层解引用)// 8. 数组/切片转换let array = [1, 2, 3, 4, 5];let slice: &[i32] = &array;println!("数组转切片: {:?}", slice);// 9. 函数指针转换fn simple_function(x: i32) -> i32 {x * 2}let function_ptr: fn(i32) -> i32 = simple_function;println!("函数指针: {}", function_ptr(21));// 10. 不安全的类型转换let bytes: [u8; 4] = [0x12, 0x34, 0x56, 0x78];let number = unsafe {std::mem::transmute::<[u8; 4], i32>(bytes)};println!("不安全转换: 0x{:08x}", number);
}fn type_system_tips() {println!("\n=== 类型系统实用技巧 ===");// 1. 使用 turbofish 语法let number = "42".parse::<i32>().unwrap();let vector = Vec::<i32>::with_capacity(10);println!("Turbofish: {}, {:?}", number, vector);// 2. 类型推断调试let () = (); // 单元类型,用于模式匹配// 3. 使用 _ 占位符let _unused_variable = 42;let _ = "临时值不会被使用";// 4. 编译时类型检查const _: () = {// 编译时断言let _: [(); 0] = [(); std::mem::size_of::<usize>()];};// 5. 使用 mem::replace 和 mem::takeuse std::mem;let mut value = Some(String::from("hello"));let taken = mem::take(&mut value); // 取出值,留下Noneprintln!("mem::take: taken={:?}, value={:?}", taken, value);// 6. 类型大小信息println!("类型大小信息:");println!("  i32: {}字节", mem::size_of::<i32>());println!("  String: {}字节", mem::size_of::<String>());println!("  &str: {}字节", mem::size_of::<&str>());println!("  Option<i32>: {}字节", mem::size_of::<Option<i32>>());// 7. 内存对齐println!("内存对齐:");println!("  i32 对齐: {}字节", mem::align_of::<i32>());println!("  f64 对齐: {}字节", mem::align_of::<f64>());// 8. 零成本抽象验证fn process_numbers(numbers: &[i32]) -> i32 {numbers.iter().sum()}let numbers = [1, 2, 3, 4, 5];let sum = process_numbers(&numbers);println!("零成本抽象: 总和 = {}", sum);
}

通过本章的全面学习,你已经深入掌握了Rust的变量系统和类型系统。从基础的变量声明到复杂的类型推断模式,你现在应该能够熟练地使用Rust的类型系统来编写安全、高效的代码。在下一章中,我们将探讨Rust的控制流结构。

http://www.dtcms.com/a/560856.html

相关文章:

  • pyside6 qt 事件循环
  • Secertpad搭建
  • 吞吐量、延迟、内存:深入理解垃圾回收的“三元悖论”
  • List接口和常用方法
  • 计算机一级考试网站怎么做用织梦系统做网站产权
  • Java 数据结构第二十八期:反射、枚举以及 lambda 表达式
  • Linux 磁盘分区与系统监控完全指南
  • 是普通网站地图好还是rss地图好一点网站建设申请费用
  • 使用Graphics2D创建滑块验证码
  • Flutter provide框架内部实现原理刨析
  • 关于rpm,yum,apt
  • 15.6.Bat脚本编写
  • 景德镇网站制作广告法
  • 可以做头像的网站网站区域名是什么
  • 新手记录使用uniapp-x开发鸿蒙应用
  • Linux+Apache+MySQL+PHP 架构下搭建 Discuz 社区论坛
  • 可替代Github Copilot的插件分享CodeGeeX
  • Ubuntu学习笔记
  • 双非大学生自学鸿蒙5.0零基础入门到项目实战 - 歌曲列表
  • 双非大学生自学鸿蒙5.0零基础入门到项目实战 -ArkTs核心
  • UVa 10989 Bomb Divide and Conquer
  • 【Linux】版本控制器Git和调试器—gdb/cgdb的使用
  • 怎么把个人做的网站上传到网上wordpress用户名钩子
  • 成都网站排名网站添加邮件发送怎么做
  • Spring AI 极简入门:15分钟集成AI到SpringBoot应用
  • 临潼城市建设局网站外资公司注册
  • 1.基础--数据库相关概念
  • 使用DTS迁移工具迁移oracle到DM
  • langchain agent的短期记忆
  • 使用DrissionPage和自动化技术实现得物鞋子信息爬取