第6章 结构体与方法

文章目录
- 第6章 结构体与方法
- 6.1 定义和实例化结构体
- 6.1.1 基本结构体定义
- 6.1.2 元组结构体
- 6.1.3 结构体高级特性
- 6.2 方法语法
- 6.2.1 基本方法定义
- 6.2.2 高级方法特性
- 6.3 关联函数
- 6.3.1 关联函数基础
- 6.3.2 高级关联函数模式
- 6.4 元组结构体进阶
- 6.4.1 元组结构体的高级用法
第6章 结构体与方法
6.1 定义和实例化结构体
6.1.1 基本结构体定义
结构体是Rust中创建自定义数据类型的主要方式,让我们从基础开始深入理解结构体的定义和使用。
fn basic_struct_definition() {println!("=== 基本结构体定义 ===");// 1. 定义简单的结构体#[derive(Debug)]struct User {username: String,email: String,sign_in_count: u64,active: bool,}// 2. 实例化结构体let user1 = User {email: String::from("someone@example.com"),username: String::from("someusername123"),active: true,sign_in_count: 1,};println!("用户1: {:?}", user1);// 3. 访问结构体字段println!("用户名: {}", user1.username);println!("邮箱: {}", user1.email);println!("活跃状态: {}", user1.active);println!("登录次数: {}", user1.sign_in_count);// 4. 修改结构体字段(需要mut)let mut user2 = User {email: String::from("another@example.com"),username: String::from("anotheruser"),active: true,sign_in_count: 0,};user2.sign_in_count = 1;user2.active = false;println!("修改后的用户2: {:?}", user2);// 5. 字段初始化简写let email = String::from("shorthand@example.com");let username = String::from("shorthanduser");let user3 = User {email, // 字段名与变量名相同时可以省略username, // 同上active: true,sign_in_count: 1,};println!("简写语法用户: {:?}", user3);// 6. 结构体更新语法let user4 = User {email: String::from("update@example.com"),username: String::from("updateuser"),..user3 // 使用user3的其他字段};println!("更新语法用户: {:?}", user4);
}fn struct_instantiation_patterns() {println!("\n=== 结构体实例化模式 ===");// 1. 函数式实例化fn create_user(email: String, username: String) -> User {User {email,username,active: true,sign_in_count: 1,}}let user = create_user(String::from("functional@example.com"),String::from("functionaluser"),);println!("函数式创建: {:?}", user);// 2. 构建器模式let user = UserBuilder::new().email("builder@example.com").username("builderuser").build();println!("构建器模式: {:?}", user);// 3. 默认值实例化#[derive(Debug, Default)]struct Config {timeout: u32,retries: u32,debug_mode: bool,}let config = Config::default();println!("默认配置: {:?}", config);let custom_config = Config {timeout: 30,..Config::default()};println!("自定义配置: {:?}", custom_config);
}// 构建器模式实现
struct UserBuilder {email: Option<String>,username: Option<String>,active: Option<bool>,sign_in_count: Option<u64>,
}impl UserBuilder {fn new() -> Self {UserBuilder {email: None,username: None,active: None,sign_in_count: None,}}fn email(mut self, email: &str) -> Self {self.email = Some(email.to_string());self}fn username(mut self, username: &str) -> Self {self.username = Some(username.to_string());self}fn active(mut self, active: bool) -> Self {self.active = Some(active);self}fn sign_in_count(mut self, count: u64) -> Self {self.sign_in_count = Some(count);self}fn build(self) -> User {User {email: self.email.unwrap_or_else(|| "default@example.com".to_string()),username: self.username.unwrap_or_else(|| "defaultuser".to_string()),active: self.active.unwrap_or(true),sign_in_count: self.sign_in_count.unwrap_or(1),}}
}fn advanced_struct_features() {println!("\n=== 高级结构体特性 ===");// 1. 结构体与所有权ownership_in_structs();// 2. 结构体内存布局struct_memory_layout();// 3. 结构体模式匹配struct_pattern_matching();
}fn ownership_in_structs() {println!("\n=== 结构体与所有权 ===");// 结构体可以包含拥有所有权的数据#[derive(Debug)]struct Article {title: String, // 拥有所有权content: String, // 拥有所有权views: u32, // 拷贝语义}let article = Article {title: String::from("Rust所有权详解"),content: String::from("这是关于Rust所有权的详细内容..."),views: 1000,};println!("文章: {:?}", article);// 移动结构体实例let moved_article = article;// println!("{:?}", article); // 错误!article已被移动// 结构体字段的所有权let title = moved_article.title; // 移动title字段的所有权// println!("{}", moved_article.title); // 错误!title已被移动println!("标题: {}", title);println!("内容: {}", moved_article.content); // 这个字段仍然可用println!("浏览量: {}", moved_article.views); // 这个字段仍然可用// 包含引用的结构体需要生命周期注解struct ArticleView<'a> {title: &'a str,preview: &'a str,}let full_article = String::from("这是一篇完整的文章内容...");let article_view = ArticleView {title: "文章标题",preview: &full_article[0..10],};println!("文章视图: {} - {}", article_view.title, article_view.preview);
}fn struct_memory_layout() {println!("\n=== 结构体内存布局 ===");use std::mem;// 1. 基本结构体大小#[derive(Debug)]struct SimpleStruct {a: i32,b: i32,c: i32,}let simple = SimpleStruct { a: 1, b: 2, c: 3 };println!("简单结构体大小: {} 字节", mem::size_of_val(&simple));println!("字段a大小: {} 字节", mem::size_of_val(&simple.a));println!("字段b大小: {} 字节", mem::size_of_val(&simple.b));println!("字段c大小: {} 字节", mem::size_of_val(&simple.c));// 2. 内存对齐#[repr(C)]struct AlignedStruct {a: u8, // 1字节b: u32, // 4字节c: u16, // 2字节}let aligned = AlignedStruct { a: 1, b: 2, c: 3 };println!("对齐结构体大小: {} 字节", mem::size_of_val(&aligned));println!("u8对齐: {} 字节", mem::align_of::<u8>());println!("u32对齐: {} 字节", mem::align_of::<u32>());println!("u16对齐: {} 字节", mem::align_of::<u16>());// 3. 打包结构体#[repr(packed)]struct PackedStruct {a: u8,b: u32,c: u16,}let packed = PackedStruct { a: 1, b: 2, c: 3 };println!("打包结构体大小: {} 字节", mem::size_of_val(&packed));// 4. 零大小类型优化struct ZeroSized;#[derive(Debug)]struct WithZST {data: i32,_marker: ZeroSized,}let with_zst = WithZST { data: 42, _marker: ZeroSized };println!("包含ZST的结构体大小: {} 字节", mem::size_of_val(&with_zst));
}fn struct_pattern_matching() {println!("\n=== 结构体模式匹配 ===");#[derive(Debug)]struct Point {x: i32,y: i32,}#[derive(Debug)]struct Rectangle {top_left: Point,bottom_right: Point,}let rect = Rectangle {top_left: Point { x: 0, y: 10 },bottom_right: Point { x: 20, y: 0 },};// 1. 基本结构体模式匹配match rect.top_left {Point { x: 0, y } => println!("点在Y轴上,y = {}", y),Point { x, y: 0 } => println!("点在X轴上,x = {}", x),Point { x, y } => println!("点在 ({}, {})", x, y),}// 2. 嵌套结构体模式匹配match rect {Rectangle { top_left: Point { x: x1, y: y1 }, bottom_right: Point { x: x2, y: y2 } } if x1 < x2 && y1 > y2 => {println!("有效矩形: ({}, {}) 到 ({}, {})", x1, y1, x2, y2);},_ => println!("无效矩形"),}// 3. 使用 .. 忽略字段match rect.top_left {Point { x, .. } => println!("点的x坐标: {}", x),}// 4. 绑定变量match rect {Rectangle { top_left: point @ Point { x: 0, .. }, .. } => {println!("顶部在Y轴上的点: {:?}", point);},_ => println!("其他情况"),}// 5. if let 简洁语法if let Rectangle { top_left: Point { x: 0, y }, bottom_right: Point { x: bx, y: by } } = rect {println!("矩形从Y轴开始: y1={}, 右下角=({}, {})", y, bx, by);}
}
6.1.2 元组结构体
元组结构体结合了元组和结构体的特性,适用于需要命名整个元组但不需要命名字段的情况。
fn tuple_structs() {println!("=== 元组结构体 ===");// 1. 基本元组结构体struct Color(u8, u8, u8);struct Point(i32, i32, i32);let black = Color(0, 0, 0);let white = Color(255, 255, 255);let origin = Point(0, 0, 0);println!("黑色: ({}, {}, {})", black.0, black.1, black.2);println!("白色: ({}, {}, {})", white.0, white.1, white.2);println!("原点: ({}, {}, {})", origin.0, origin.1, origin.2);// 2. 元组结构体解构let Color(r, g, b) = black;println!("解构颜色: R={}, G={}, B={}", r, g, b);// 3. 元组结构体模式匹配match origin {Point(0, 0, 0) => println!("这是原点"),Point(x, 0, 0) => println!("在X轴上: {}", x),Point(0, y, 0) => println!("在Y轴上: {}", y),Point(0, 0, z) => println!("在Z轴上: {}", z),Point(x, y, z) => println!("在空间点: ({}, {}, {})", x, y, z),}// 4. 新类型模式(Newtype Pattern)newtype_pattern();// 5. 单元结构体unit_structs();
}fn newtype_pattern() {println!("\n=== 新类型模式 ===");// 新类型模式:用元组结构体包装现有类型以提供类型安全和抽象// 基础类型type UserId = u32;type ProductId = u32;// 新类型包装struct UserIdWrapper(UserId);struct ProductIdWrapper(ProductId);impl UserIdWrapper {fn new(id: u32) -> Self {UserIdWrapper(id)}fn value(&self) -> u32 {self.0}}impl ProductIdWrapper {fn new(id: u32) -> Self {ProductIdWrapper(id)}fn value(&self) -> u32 {self.0}}// 使用新类型提供类型安全fn get_user_name(user_id: UserIdWrapper) -> String {format!("用户{}", user_id.value())}fn get_product_name(product_id: ProductIdWrapper) -> String {format!("产品{}", product_id.value())}let user_id = UserIdWrapper::new(123);let product_id = ProductIdWrapper::new(456);println!("用户名: {}", get_user_name(user_id));println!("产品名: {}", get_product_name(product_id));// 下面的代码会导致编译错误,提供了类型安全// get_user_name(product_id); // 错误!期望UserIdWrapper,得到ProductIdWrapper// 更复杂的新类型示例struct Email(String);impl Email {fn new(email: &str) -> Result<Self, String> {if email.contains('@') {Ok(Email(email.to_string()))} else {Err("无效的电子邮件地址".to_string())}}fn value(&self) -> &str {&self.0}}let email = Email::new("user@example.com").unwrap();println!("电子邮件: {}", email.value());
}fn unit_structs() {println!("\n=== 单元结构体 ===");// 单元结构体:没有任何字段的结构体// 1. 基本单元结构体struct Marker;struct Nothing;let marker = Marker;let nothing = Nothing;println!("单元结构体大小: {} 字节", std::mem::size_of_val(&marker));// 2. 单元结构体实现 traitimpl Marker {fn mark(&self) {println!("标记位置");}}marker.mark();// 3. 单元结构体在泛型中的应用struct Wrapper<T> {value: T,_marker: Marker,}let wrapped = Wrapper {value: 42,_marker: Marker,};println!("包装的值: {}", wrapped.value);// 4. 单元结构体作为类型标记struct Kilometers;struct Miles;struct Distance<T> {value: f64,_unit: std::marker::PhantomData<T>,}impl Distance<Kilometers> {fn to_miles(&self) -> Distance<Miles> {Distance {value: self.value * 0.621371,_unit: std::marker::PhantomData,}}}impl Distance<Miles> {fn to_kilometers(&self) -> Distance<Kilometers> {Distance {value: self.value * 1.60934,_unit: std::marker::PhantomData,}}}let distance_km = Distance::<Kilometers> {value: 100.0,_unit: std::marker::PhantomData,};let distance_miles = distance_km.to_miles();println!("100公里 = {:.2} 英里", distance_miles.value);let back_to_km = distance_miles.to_kilometers();println("{:.2} 英里 = {:.2} 公里", distance_miles.value, back_to_km.value);
}
6.1.3 结构体高级特性
探索结构体的一些高级特性和使用模式。
fn advanced_struct_techniques() {println!("=== 结构体高级特性 ===");// 1. 泛型结构体generic_structs();// 2. 结构体与trait约束structs_with_trait_bounds();// 3. 结构体继承模拟struct_inheritance_simulation();// 4. 结构体与模式structural_patterns();
}fn generic_structs() {println!("\n=== 泛型结构体 ===");// 1. 基本泛型结构体struct Pair<T> {first: T,second: T,}let int_pair = Pair { first: 1, second: 2 };let string_pair = Pair { first: "hello", second: "world" };println!("整数对: {}, {}", int_pair.first, int_pair.second);println!("字符串对: {}, {}", string_pair.first, string_pair.second);// 2. 多个类型参数的泛型结构体struct Either<L, R> {left: Option<L>,right: Option<R>,}let left_value = Either::<i32, &str> {left: Some(42),right: None,};let right_value = Either::<i32, &str> {left: None,right: Some("hello"),};// 3. 泛型结构体方法实现impl<T> Pair<T> {fn new(first: T, second: T) -> Self {Pair { first, second }}fn into_tuple(self) -> (T, T) {(self.first, self.second)}}let pair = Pair::new(10, 20);let tuple = pair.into_tuple();println!("转换为元组: {:?}", tuple);// 4. 特定类型的实现impl Pair<f64> {fn distance_from_origin(&self) -> f64 {(self.first.powi(2) + self.second.powi(2)).sqrt()}}let float_pair = Pair::new(3.0, 4.0);println!("到原点的距离: {}", float_pair.distance_from_origin());// 5. 关联类型与泛型trait Container {type Item;fn get_item(&self) -> &Self::Item;}struct BoxContainer<T> {item: T,}impl<T> Container for BoxContainer<T> {type Item = T;fn get_item(&self) -> &Self::Item {&self.item}}let container = BoxContainer { item: 42 };println!("容器中的项: {}", container.get_item());
}fn structs_with_trait_bounds() {println!("\n=== 带trait约束的结构体 ===");use std::fmt::Display;use std::cmp::PartialOrd;// 1. 带trait约束的泛型结构体struct DisplayablePair<T: Display> {first: T,second: T,}impl<T: Display> DisplayablePair<T> {fn display(&self) {println!("({}, {})", self.first, self.second);}}let display_pair = DisplayablePair { first: 1, second: 2 };display_pair.display();// 2. 多个trait约束struct ComparablePair<T: PartialOrd + Display> {first: T,second: T,}impl<T: PartialOrd + Display> ComparablePair<T> {fn max(&self) -> &T {if self.first > self.second {&self.first} else {&self.second}}fn min(&self) -> &T {if self.first < self.second {&self.first} else {&self.second}}}let comp_pair = ComparablePair { first: 10, second: 20 };println!("最大值: {}, 最小值: {}", comp_pair.max(), comp_pair.min());// 3. where子句简化复杂约束struct ComplexPair<T, U>whereT: Display + Clone,U: Display + PartialEq,{left: T,right: U,}impl<T, U> ComplexPair<T, U>whereT: Display + Clone,U: Display + PartialEq,{fn new(left: T, right: U) -> Self {ComplexPair { left, right }}fn display_both(&self) {println!("左: {}, 右: {}", self.left, self.right);}}let complex = ComplexPair::new(42, "hello");complex.display_both();// 4. 默认泛型类型参数struct AddablePair<T = i32> {first: T,second: T,}// 使用默认类型参数let default_pair = AddablePair { first: 1, second: 2 };// 指定类型参数let float_pair = AddablePair::<f64> { first: 1.5, second: 2.5 };
}fn struct_inheritance_simulation() {println!("\n=== 结构体继承模拟 ===");// Rust没有传统继承,但可以使用组合和trait模拟类似功能// 1. 基础结构体struct Animal {name: String,age: u32,}impl Animal {fn new(name: &str, age: u32) -> Self {Animal {name: name.to_string(),age,}}fn speak(&self) {println!("{} 发出声音", self.name);}fn info(&self) {println!("名字: {}, 年龄: {}", self.name, self.age);}}// 2. 使用组合模拟继承struct Dog {animal: Animal, // 组合而不是继承breed: String,}impl Dog {fn new(name: &str, age: u32, breed: &str) -> Self {Dog {animal: Animal::new(name, age),breed: breed.to_string(),}}// 委托方法fn speak(&self) {println!("{} 汪汪叫!", self.animal.name);}fn info(&self) {self.animal.info();println!("品种: {}", self.breed);}// 特有方法fn fetch(&self) {println!("{} 在接球!", self.animal.name);}}// 3. 使用trait共享行为trait Pet {fn name(&self) -> &str;fn age(&self) -> u32;fn speak(&self);// 默认实现fn info(&self) {println!("宠物: {}, 年龄: {}", self.name(), self.age());}}impl Pet for Animal {fn name(&self) -> &str {&self.name}fn age(&self) -> u32 {self.age}fn speak(&self) {println!("{} 发出声音", self.name);}}impl Pet for Dog {fn name(&self) -> &str {&self.animal.name}fn age(&self) -> u32 {self.animal.age}fn speak(&self) {println!("{} 汪汪叫!", self.animal.name);}fn info(&self) {println!("狗狗: {}, 年龄: {}, 品种: {}", self.name(), self.age(), self.breed);}}let animal = Animal::new("动物", 3);let dog = Dog::new("旺财", 2, "金毛");// 使用trait对象实现多态let pets: Vec<&dyn Pet> = vec![&animal, &dog];for pet in pets {pet.info();pet.speak();println!("---");}
}fn structural_patterns() {println!("\n=== 结构体设计模式 ===");// 1. 建造者模式builder_pattern();// 2. 类型状态模式typestate_pattern();// 3. 新类型模式进阶advanced_newtype_pattern();
}fn builder_pattern() {println!("\n=== 建造者模式 ===");#[derive(Debug)]struct HttpRequest {method: String,url: String,headers: Vec<(String, String)>,body: Option<String>,}struct HttpRequestBuilder {method: Option<String>,url: Option<String>,headers: Vec<(String, String)>,body: Option<String>,}impl HttpRequestBuilder {fn new() -> Self {HttpRequestBuilder {method: None,url: None,headers: Vec::new(),body: None,}}fn method(mut self, method: &str) -> Self {self.method = Some(method.to_string());self}fn url(mut self, url: &str) -> Self {self.url = Some(url.to_string());self}fn header(mut self, key: &str, value: &str) -> Self {self.headers.push((key.to_string(), value.to_string()));self}fn body(mut self, body: &str) -> Self {self.body = Some(body.to_string());self}fn build(self) -> Result<HttpRequest, String> {let method = self.method.ok_or("方法必须设置")?;let url = self.url.ok_or("URL必须设置")?;Ok(HttpRequest {method,url,headers: self.headers,body: self.body,})}}let request = HttpRequestBuilder::new().method("GET").url("https://api.example.com/data").header("Content-Type", "application/json").header("Authorization", "Bearer token").build().unwrap();println!("HTTP请求: {:?}", request);
}fn typestate_pattern() {println!("\n=== 类型状态模式 ===");// 类型状态模式:使用类型系统在编译时强制执行状态转换规则// 状态标记struct Pending;struct Processing;struct Completed;struct Failed;// 泛型结构体,状态由类型参数表示struct Request<State> {id: u32,data: String,state: std::marker::PhantomData<State>,}impl Request<Pending> {fn new(id: u32, data: &str) -> Self {Request {id,data: data.to_string(),state: std::marker::PhantomData,}}fn start_processing(self) -> Request<Processing> {println!("请求 {} 开始处理", self.id);Request {id: self.id,data: self.data,state: std::marker::PhantomData,}}}impl Request<Processing> {fn complete(self) -> Request<Completed> {println!("请求 {} 处理完成", self.id);Request {id: self.id,data: self.data,state: std::marker::PhantomData,}}fn fail(self) -> Request<Failed> {println!("请求 {} 处理失败", self.id);Request {id: self.id,data: self.data,state: std::marker::PhantomData,}}}impl Request<Completed> {fn get_result(&self) -> &str {&self.data}}impl Request<Failed> {fn get_error(&self) -> &str {&self.data}}// 使用类型状态模式let request = Request::<Pending>::new(1, "请求数据");let processing = request.start_processing();let completed = processing.complete();println!("完成的结果: {}", completed.get_result());// 编译时防止非法状态转换// let pending = Request::<Pending>::new(2, "另一个请求");// pending.complete(); // 错误!Pending状态不能直接完成
}fn advanced_newtype_pattern() {println!("\n=== 进阶新类型模式 ===");use std::ops::{Add, Deref};// 1. 新类型包装数值类型#[derive(Debug, Clone, Copy)]struct Meters(f64);impl Meters {fn new(value: f64) -> Self {Meters(value)}}// 实现Deref以便自动解引用impl Deref for Meters {type Target = f64;fn deref(&self) -> &Self::Target {&self.0}}// 实现Add trait支持加法impl Add for Meters {type Output = Meters;fn add(self, other: Meters) -> Meters {Meters(self.0 + other.0)}}let distance1 = Meters::new(5.5);let distance2 = Meters::new(3.2);let total = distance1 + distance2;println!("距离1: {}米", *distance1);println!("距离2: {}米", *distance2);println!("总距离: {}米", *total);// 2. 新类型包装字符串struct Username(String);impl Username {fn new(username: &str) -> Result<Self, String> {if username.len() < 3 {Err("用户名太短".to_string())} else if username.len() > 20 {Err("用户名太长".to_string())} else if !username.chars().all(|c| c.is_alphanumeric()) {Err("用户名只能包含字母和数字".to_string())} else {Ok(Username(username.to_string()))}}}impl Deref for Username {type Target = str;fn deref(&self) -> &Self::Target {&self.0}}match Username::new("user123") {Ok(username) => println!("有效用户名: {}", &*username),Err(e) => println!("无效用户名: {}", e),}match Username::new("ab") {Ok(username) => println!("有效用户名: {}", &*username),Err(e) => println!("无效用户名: {}", e),}// 3. 新类型实现自定义traittrait Validatable {fn is_valid(&self) -> bool;}impl Validatable for Username {fn is_valid(&self) -> bool {self.len() >= 3 && self.len() <= 20 && self.chars().all(|c| c.is_alphanumeric())}}let username = Username::new("validuser").unwrap();println!("用户名有效: {}", username.is_valid());
}
6.2 方法语法
6.2.1 基本方法定义
方法是与结构体实例关联的函数,让我们深入理解方法的定义和使用。
fn basic_method_syntax() {println!("=== 基本方法语法 ===");#[derive(Debug)]struct Rectangle {width: u32,height: u32,}// 为Rectangle实现方法impl Rectangle {// 关联函数(静态方法)fn new(width: u32, height: u32) -> Self {Rectangle { width, height }}// 实例方法 - 不可变借用selffn area(&self) -> u32 {self.width * self.height}// 实例方法 - 可变借用selffn resize(&mut self, width: u32, height: u32) {self.width = width;self.height = height;}// 实例方法 - 获取所有权selffn into_tuple(self) -> (u32, u32) {(self.width, self.height)}// 方法可以接受额外参数fn can_hold(&self, other: &Rectangle) -> bool {self.width > other.width && self.height > other.height}}// 使用关联函数创建实例let mut rect = Rectangle::new(30, 50);println!("矩形: {:?}", rect);// 调用实例方法println!("面积: {}", rect.area());// 调用可变方法rect.resize(40, 60);println!("调整后: {:?}", rect);println!("新面积: {}", rect.area());// 测试can_hold方法let small = Rectangle::new(10, 20);let large = Rectangle::new(50, 50);println!("大矩形能容纳小矩形: {}", large.can_hold(&small));println!("小矩形能容纳大矩形: {}", small.can_hold(&large));// 调用消耗self的方法let tuple = rect.into_tuple();println!("转换为元组: {:?}", tuple);// println!("{:?}", rect); // 错误!rect已被消耗
}fn method_receiver_types() {println!("\n=== 方法接收器类型 ===");#[derive(Debug)]struct Counter {value: i32,}impl Counter {// 1. &self - 不可变借用fn get_value(&self) -> i32 {self.value}// 2. &mut self - 可变借用fn increment(&mut self) {self.value += 1;}fn decrement(&mut self) {self.value -= 1;}// 3. self - 获取所有权fn consume(self) -> i32 {self.value}// 4. 没有self - 关联函数fn default() -> Self {Counter { value: 0 }}// 5. 返回Self的关联函数fn with_value(value: i32) -> Self {Counter { value }}}let mut counter = Counter::default();println!("初始值: {}", counter.get_value());counter.increment();counter.increment();println!("增加两次后: {}", counter.get_value());counter.decrement();println!("减少一次后: {}", counter.get_value());let value = counter.consume();println!("消耗后获取的值: {}", value);// println!("{:?}", counter); // 错误!counter已被消耗// 使用关联函数创建新实例let new_counter = Counter::with_value(100);println!("新计数器值: {}", new_counter.get_value());// 方法链调用let result = Counter::with_value(10).increment() // 返回&mut Self以便链式调用.get_value();println!("链式调用结果: {}", result);
}// 为Counter实现链式调用的方法
impl Counter {fn increment_chain(&mut self) -> &mut Self {self.value += 1;self}fn decrement_chain(&mut self) -> &mut Self {self.value -= 1;self}fn set_value(&mut self, value: i32) -> &mut Self {self.value = value;self}
}fn method_visibility() {println!("\n=== 方法可见性 ===");// Rust使用pub关键字控制可见性pub struct BankAccount {balance: i32, // 私有字段account_number: String, // 私有字段}impl BankAccount {// 公开的关联函数pub fn new(account_number: &str, initial_balance: i32) -> Self {BankAccount {balance: initial_balance,account_number: account_number.to_string(),}}// 公开的方法pub fn get_balance(&self) -> i32 {self.balance}pub fn deposit(&mut self, amount: i32) -> Result<(), String> {if amount <= 0 {return Err("存款金额必须为正数".to_string());}self.balance += amount;Ok(())}pub fn withdraw(&mut self, amount: i32) -> Result<(), String> {if amount <= 0 {return Err("取款金额必须为正数".to_string());}if amount > self.balance {return Err("余额不足".to_string());}self.balance -= amount;Ok(())}// 私有方法 - 只能在模块内部调用fn validate_account(&self) -> bool {!self.account_number.is_empty() && self.balance >= 0}// 公开方法可以调用私有方法pub fn is_valid(&self) -> bool {self.validate_account()}}let mut account = BankAccount::new("123456", 1000);println!("初始余额: {}", account.get_balance());match account.deposit(500) {Ok(()) => println!("存款成功"),Err(e) => println!("存款失败: {}", e),}match account.withdraw(2000) {Ok(()) => println!("取款成功"),Err(e) => println!("取款失败: {}", e),}println!("最终余额: {}", account.get_balance());println!("账户有效: {}", account.is_valid());// 无法直接访问私有字段// println!("{}", account.balance); // 错误!// account.validate_account(); // 错误!
}
6.2.2 高级方法特性
探索方法的一些高级特性和使用模式。
fn advanced_method_features() {println!("=== 高级方法特性 ===");// 1. 泛型方法generic_methods();// 2. 方法重载模拟method_overloading_simulation();// 3. 方法中的模式匹配pattern_matching_in_methods();// 4. 方法与生命周期methods_and_lifetimes();
}fn generic_methods() {println!("\n=== 泛型方法 ===");struct Container<T> {value: T,}impl<T> Container<T> {// 泛型方法 - 使用结构体的泛型参数fn get_value(&self) -> &T {&self.value}// 泛型方法 - 有自己的泛型参数fn map<U, F>(self, f: F) -> Container<U>whereF: FnOnce(T) -> U,{Container { value: f(self.value) }}// 泛型方法 - 多个泛型参数fn combine<U, V, F>(self, other: Container<U>, f: F) -> Container<V>whereF: FnOnce(T, U) -> V,{Container { value: f(self.value, other.value) }}}// 为特定类型实现方法impl Container<i32> {fn square(&self) -> i32 {self.value * self.value}}// 使用泛型方法let container = Container { value: 42 };println!("值: {}", container.get_value());let squared = Container { value: 5 }.square();println!("平方: {}", squared);// 使用map方法let string_container = Container { value: 42 }.map(|x| x.to_string());println!("映射后: {}", string_container.get_value());// 使用combine方法let container1 = Container { value: 10 };let container2 = Container { value: 20 };let combined = container1.combine(container2, |a, b| a + b);println!("合并后: {}", combined.get_value());// 更复杂的泛型方法示例advanced_generic_methods();
}fn advanced_generic_methods() {println!("\n=== 进阶泛型方法 ===");use std::ops::Add;use std::fmt::Display;struct Calculator;impl Calculator {// 泛型方法 with trait boundsfn add<T: Add<Output = T> + Copy>(&self, a: T, b: T) -> T {a + b}// 使用where子句fn multiply<T>(&self, a: T, b: T) -> TwhereT: std::ops::Mul<Output = T> + Copy,{a * b}// 返回impl Traitfn process<T>(&self, value: T) -> impl DisplaywhereT: Display + Clone,{format!("处理后的: {}", value)}}let calc = Calculator;let sum = calc.add(5, 3);println!("5 + 3 = {}", sum);let product = calc.multiply(4.5, 2.0);println!("4.5 * 2.0 = {}", product);let processed = calc.process("hello");println!("{}", processed);
}fn method_overloading_simulation() {println!("\n=== 方法重载模拟 ===");// Rust不支持传统的方法重载,但可以使用泛型或不同的方法名模拟struct MathUtils;impl MathUtils {// 方法1: 使用不同的方法名fn add_i32(&self, a: i32, b: i32) -> i32 {a + b}fn add_f64(&self, a: f64, b: f64) -> f64 {a + b}// 方法2: 使用泛型fn add<T>(&self, a: T, b: T) -> TwhereT: std::ops::Add<Output = T>,{a + b}// 方法3: 使用trait对象fn display_value(&self, value: &dyn std::fmt::Display) -> String {format!("值: {}", value)}}let math = MathUtils;// 使用不同方法名println!("i32加法: {}", math.add_i32(5, 3));println!("f64加法: {}", math.add_f64(5.5, 3.2));// 使用泛型方法println!("泛型i32加法: {}", math.add(10, 20));println!("泛型f64加法: {}", math.add(10.5, 20.3));// 使用trait对象println!("{}", math.display_value(&42));println!("{}", math.display_value(&"hello"));// 更复杂的重载模拟advanced_overloading_simulation();
}fn advanced_overloading_simulation() {println!("\n=== 进阶重载模拟 ===");use std::fmt::Display;struct Printer;impl Printer {// 模拟可变参数 - 使用切片fn print_values<T: Display>(&self, values: &[T]) {for (i, value) in values.iter().enumerate() {println!("参数{}: {}", i + 1, value);}}// 模拟可选参数 - 使用Optionfn print_with_prefix<T: Display>(&self, value: T, prefix: Option<&str>) {match prefix {Some(p) => println!("{}: {}", p, value),None => println!("{}", value),}}// 模拟默认参数 - 使用默认值fn print_with_default<T: Display>(&self, value: T, separator: &str) {println!("{}{}", value, separator);}}let printer = Printer;// 可变参数模拟printer.print_values(&[1, 2, 3, 4, 5]);printer.print_values(&["a", "b", "c"]);// 可选参数模拟printer.print_with_prefix("hello", Some("消息"));printer.print_with_prefix("world", None);// 默认参数模拟printer.print_with_default("hello", "!");printer.print_with_default("world", ".");
}fn pattern_matching_in_methods() {println!("\n=== 方法中的模式匹配 ===");#[derive(Debug)]enum Status {Success(String),Error(String),Loading(f32),}struct ResponseHandler;impl ResponseHandler {// 在方法中使用matchfn handle_status(&self, status: Status) {match status {Status::Success(message) => {println!("成功: {}", message);},Status::Error(error) => {println!("错误: {}", error);},Status::Loading(progress) => {println!("加载中: {:.1}%", progress * 100.0);},}}// 使用if let简化匹配fn check_success(&self, status: &Status) -> bool {if let Status::Success(_) = status {true} else {false}}// 在方法参数中使用模式fn process_result(&self, (code, message): (u32, &str)) {println!("代码: {}, 消息: {}", code, message);}// 复杂的模式匹配fn analyze_data(&self, data: &[Option<i32>]) {for (i, item) in data.iter().enumerate() {match item {Some(value @ 1..=100) => {println!("位置{}: 有效值 {}", i, value);},Some(value) if *value < 0 => {println!("位置{}: 负值 {}", i, value);},Some(value) => {println!("位置{}: 大值 {}", i, value);},None => {println!("位置{}: 无数据", i);},}}}}let handler = ResponseHandler;// 测试状态处理handler.handle_status(Status::Success("操作完成".to_string()));handler.handle_status(Status::Error("网络错误".to_string()));handler.handle_status(Status::Loading(0.75));// 测试成功检查let success_status = Status::Success("测试".to_string());println!("是否是成功状态: {}", handler.check_success(&success_status));// 测试元组处理handler.process_result((200, "OK"));// 测试数据分析let data = vec![Some(50), None, Some(-5), Some(200)];handler.analyze_data(&data);
}fn methods_and_lifetimes() {println!("\n=== 方法与生命周期 ===");// 1. 结构体包含引用需要生命周期注解struct TextProcessor<'a> {text: &'a str,processed: bool,}impl<'a> TextProcessor<'a> {// 方法通常不需要显式生命周期注解,编译器可以推断fn new(text: &'a str) -> Self {TextProcessor {text,processed: false,}}fn get_text(&self) -> &'a str {self.text}// 返回的引用生命周期与self相同fn get_first_word(&self) -> &'a str {self.text.split_whitespace().next().unwrap_or("")}// 多个生命周期参数fn combine_texts<'b>(&self, other: &'b str) -> String where'a: 'b, // 生命周期约束:'a 至少和 'b 一样长{format!("{} {}", self.text, other)}}let text = "Hello World";let processor = TextProcessor::new(text);println!("文本: {}", processor.get_text());println!("第一个单词: {}", processor.get_first_word());let other_text = "Rust Programming";let combined = processor.combine_texts(other_text);println!("合并文本: {}", combined);// 2. 复杂的生命周期场景complex_lifetime_scenarios();
}fn complex_lifetime_scenarios() {println!("\n=== 复杂生命周期场景 ===");struct StringSplitter<'a, 'b> {text: &'a str,delimiter: &'b str,}impl<'a, 'b> StringSplitter<'a, 'b> {fn new(text: &'a str, delimiter: &'b str) -> Self {StringSplitter { text, delimiter }}// 返回的迭代器需要生命周期注解fn split(&self) -> impl Iterator<Item = &'a str> {self.text.split(self.delimiter)}// 高级生命周期模式fn find_longest<'c>(&self, other: &'c str) -> &'c str where'a: 'c,{if self.text.len() > other.len() {self.text} else {other}}}let text = "apple,banana,cherry";let splitter = StringSplitter::new(text, ",");println!("分割结果:");for part in splitter.split() {println!(" {}", part);}let other_text = "date";let longest = splitter.find_longest(other_text);println!("较长的文本: {}", longest);// 3. 生命周期省略规则在方法中的应用lifetime_elision_in_methods();
}fn lifetime_elision_in_methods() {println!("\n=== 方法中的生命周期省略 ===");// Rust有三条生命周期省略规则,在方法中经常应用struct StringWrapper<'a> {data: &'a str,}impl<'a> StringWrapper<'a> {// 规则1: 每个引用参数都有自己的生命周期// 规则2: 如果只有一个输入生命周期参数,它被赋予所有输出生命周期参数fn get_data(&self) -> &str { // 等价于 &'a strself.data}// 规则3: 如果有多个输入生命周期参数,但其中一个是&self或&mut self,// 那么self的生命周期被赋予所有输出生命周期参数fn combine(&self, other: &str) -> &str { // 等价于 &'a strif self.data.len() > other.len() {self.data} else {other}}}let wrapper = StringWrapper { data: "hello" };println!("数据: {}", wrapper.get_data());let other = "world";println!("组合结果: {}", wrapper.combine(other));// 无法应用省略规则的情况struct DualWrapper<'a, 'b> {first: &'a str,second: &'b str,}impl<'a, 'b> DualWrapper<'a, 'b> {// 需要显式生命周期注解fn get_longest(&self) -> &str where'a: 'b,{if self.first.len() > self.second.len() {self.first} else {self.second}}}let dual = DualWrapper {first: "long string",second: "short",};println!("较长的字符串: {}", dual.get_longest());
}
6.3 关联函数
6.3.1 关联函数基础
关联函数是不以self作为参数的函数,通常用于构造器或其他与类型相关的功能。
fn associated_functions_basics() {println!("=== 关联函数基础 ===");#[derive(Debug)]struct Circle {radius: f64,}impl Circle {// 关联函数 - 没有self参数fn new(radius: f64) -> Self {Circle { radius }}// 另一个关联函数fn unit() -> Self {Circle { radius: 1.0 }}// 带验证的关联函数fn try_new(radius: f64) -> Result<Self, String> {if radius >= 0.0 {Ok(Circle { radius })} else {Err("半径不能为负".to_string())}}// 实例方法 - 有self参数fn area(&self) -> f64 {std::f64::consts::PI * self.radius * self.radius}}// 使用关联函数创建实例let circle1 = Circle::new(5.0);let circle2 = Circle::unit();println!("圆1: {:?}, 面积: {:.2}", circle1, circle1.area());println!("单位圆: {:?}, 面积: {:.2}", circle2, circle2.area());// 使用带验证的关联函数match Circle::try_new(3.0) {Ok(circle) => println!("创建成功: {:?}", circle),Err(e) => println!("创建失败: {}", e),}match Circle::try_new(-1.0) {Ok(circle) => println!("创建成功: {:?}", circle),Err(e) => println!("创建失败: {}", e),}// 关联函数的其他用途other_uses_of_associated_functions();
}fn other_uses_of_associated_functions() {println!("\n=== 关联函数的其他用途 ===");// 1. 工厂方法模式factory_method_pattern();// 2. 工具函数utility_functions();// 3. 常量关联函数constant_associated_functions();
}fn factory_method_pattern() {println!("\n=== 工厂方法模式 ===");#[derive(Debug)]enum ShapeType {Circle,Rectangle,Triangle,}#[derive(Debug)]struct Shape {shape_type: ShapeType,area: f64,}impl Shape {// 工厂方法 - 根据类型创建不同的形状fn create_circle(radius: f64) -> Self {Shape {shape_type: ShapeType::Circle,area: std::f64::consts::PI * radius * radius,}}fn create_rectangle(width: f64, height: f64) -> Self {Shape {shape_type: ShapeType::Rectangle,area: width * height,}}fn create_triangle(base: f64, height: f64) -> Self {Shape {shape_type: ShapeType::Triangle,area: 0.5 * base * height,}}// 通用工厂方法fn create(shape_type: ShapeType, dimensions: &[f64]) -> Result<Self, String> {match shape_type {ShapeType::Circle => {if dimensions.len() != 1 {return Err("圆形需要1个参数(半径)".to_string());}Ok(Self::create_circle(dimensions[0]))},ShapeType::Rectangle => {if dimensions.len() != 2 {return Err("矩形需要2个参数(宽,高)".to_string());}Ok(Self::create_rectangle(dimensions[0], dimensions[1]))},ShapeType::Triangle => {if dimensions.len() != 2 {return Err("三角形需要2个参数(底,高)".to_string());}Ok(Self::create_triangle(dimensions[0], dimensions[1]))},}}}// 使用工厂方法let circle = Shape::create_circle(5.0);let rectangle = Shape::create_rectangle(4.0, 6.0);let triangle = Shape::create_triangle(3.0, 4.0);println!("圆形: {:?}", circle);println!("矩形: {:?}", rectangle);println!("三角形: {:?}", triangle);// 使用通用工厂方法match Shape::create(ShapeType::Circle, &[5.0]) {Ok(shape) => println!("创建的圆形: {:?}", shape),Err(e) => println!("创建失败: {}", e),}
}fn utility_functions() {println!("\n=== 工具函数 ===");struct MathUtils;impl MathUtils {// 数学工具函数fn factorial(n: u64) -> u64 {if n <= 1 { 1 } else { n * Self::factorial(n - 1) }}fn gcd(mut a: u64, mut b: u64) -> u64 {while b != 0 {let temp = b;b = a % b;a = temp;}a}fn lcm(a: u64, b: u64) -> u64 {if a == 0 || b == 0 {0} else {(a * b) / Self::gcd(a, b)}}// 配置相关的工具函数fn default_config() -> Config {Config {timeout: 30,retries: 3,debug: false,}}fn production_config() -> Config {Config {timeout: 60,retries: 5,debug: false,}}}#[derive(Debug)]struct Config {timeout: u32,retries: u32,debug: bool,}// 使用工具函数println!("5的阶乘: {}", MathUtils::factorial(5));println!("GCD(54, 24): {}", MathUtils::gcd(54, 24));println!("LCM(12, 18): {}", MathUtils::lcm(12, 18));println!("默认配置: {:?}", MathUtils::default_config());println!("生产配置: {:?}", MathUtils::production_config());
}fn constant_associated_functions() {println!("\n=== 常量关联函数 ===");// 关联函数可以在编译时求值struct Constants;impl Constants {// 常量函数 - 在编译时求值const fn pi() -> f64 {3.141592653589793}const fn e() -> f64 {2.718281828459045}const fn golden_ratio() -> f64 {1.618033988749895}// 计算常量表达式const fn circle_area(radius: f64) -> f64 {Self::pi() * radius * radius}}// 在常量上下文中使用const PI: f64 = Constants::pi();const E: f64 = Constants::e();const UNIT_CIRCLE_AREA: f64 = Constants::circle_area(1.0);println!("π = {:.6}", PI);println!("e = {:.6}", E);println!("黄金比例 = {:.6}", Constants::golden_ratio());println!("单位圆面积 = {:.6}", UNIT_CIRCLE_AREA);// 在运行时使用let radius = 5.0;let area = Constants::circle_area(radius);println!("半径为{}的圆面积 = {:.2}", radius, area);
}
6.3.2 高级关联函数模式
探索关联函数的一些高级使用模式和技巧。
fn advanced_associated_function_patterns() {println!("=== 高级关联函数模式 ===");// 1. 单例模式singleton_pattern();// 2. 注册表模式registry_pattern();// 3. 类型转换模式conversion_patterns();// 4. 构造器模式进阶advanced_builder_pattern();
}fn singleton_pattern() {println!("\n=== 单例模式 ===");use std::sync::Mutex;use std::sync::Once;struct AppConfig {database_url: String,cache_size: usize,debug_mode: bool,}impl AppConfig {// 单例实例fn global() -> &'static Mutex<AppConfig> {static mut CONFIG: Option<Mutex<AppConfig>> = None;static ONCE: Once = Once::new();unsafe {ONCE.call_once(|| {CONFIG = Some(Mutex::new(AppConfig {database_url: "postgres://localhost:5432/mydb".to_string(),cache_size: 1000,debug_mode: cfg!(debug_assertions),}));});CONFIG.as_ref().unwrap()}}// 获取配置值的方法fn get_database_url(&self) -> &str {&self.database_url}fn get_cache_size(&self) -> usize {self.cache_size}fn is_debug_mode(&self) -> bool {self.debug_mode}}// 使用单例let config = AppConfig::global().lock().unwrap();println!("数据库URL: {}", config.get_database_url());println!("缓存大小: {}", config.get_cache_size());println!("调试模式: {}", config.is_debug_mode());// 更安全的单例实现thread_safe_singleton();
}fn thread_safe_singleton() {println!("\n=== 线程安全单例 ===");use std::sync::{Arc, RwLock};use std::sync::Once;#[derive(Debug)]struct Logger {log_level: String,}impl Logger {fn new(level: &str) -> Self {Logger {log_level: level.to_string(),}}fn log(&self, message: &str) {println!("[{}] {}", self.log_level, message);}}// 线程安全的单例struct LoggerSingleton;impl LoggerSingleton {fn instance() -> Arc<RwLock<Logger>> {static mut INSTANCE: Option<Arc<RwLock<Logger>>> = None;static ONCE: Once = Once::new();unsafe {ONCE.call_once(|| {let logger = Logger::new("INFO");INSTANCE = Some(Arc::new(RwLock::new(logger)));});INSTANCE.as_ref().unwrap().clone()}}}// 在多线程环境中安全使用let logger = LoggerSingleton::instance();{let log = logger.read().unwrap();log.log("应用程序启动");}{let mut log = logger.write().unwrap();log.log_level = "DEBUG".to_string();}{let log = logger.read().unwrap();log.log("调试信息");}
}fn registry_pattern() {println!("\n=== 注册表模式 ===");use std::collections::HashMap;// 插件系统示例trait Plugin {fn execute(&self);fn name(&self) -> &str;}struct PluginRegistry {plugins: HashMap<String, Box<dyn Plugin>>,}impl PluginRegistry {// 全局注册表实例fn global() -> &'static Mutex<PluginRegistry> {static mut REGISTRY: Option<Mutex<PluginRegistry>> = None;static ONCE: Once = Once::new();unsafe {ONCE.call_once(|| {REGISTRY = Some(Mutex::new(PluginRegistry {plugins: HashMap::new(),}));});REGISTRY.as_ref().unwrap()}}// 注册插件fn register_plugin(&mut self, name: String, plugin: Box<dyn Plugin>) {self.plugins.insert(name, plugin);}// 执行插件fn execute_plugin(&self, name: &str) -> Result<(), String> {if let Some(plugin) = self.plugins.get(name) {plugin.execute();Ok(())} else {Err(format!("插件 '{}' 未找到", name))}}// 列出所有插件fn list_plugins(&self) -> Vec<&str> {self.plugins.keys().map(|s| s.as_str()).collect()}}// 示例插件struct HelloPlugin;impl Plugin for HelloPlugin {fn execute(&self) {println!("Hello from HelloPlugin!");}fn name(&self) -> &str {"hello"}}struct GoodbyePlugin;impl Plugin for GoodbyePlugin {fn execute(&self) {println!("Goodbye from GoodbyePlugin!");}fn name(&self) -> &str {"goodbye"}}// 注册和使用插件{let mut registry = PluginRegistry::global().lock().unwrap();registry.register_plugin("hello".to_string(), Box::new(HelloPlugin));registry.register_plugin("goodbye".to_string(), Box::new(GoodbyePlugin));}// 执行插件let registry = PluginRegistry::global().lock().unwrap();println!("可用插件: {:?}", registry.list_plugins());registry.execute_plugin("hello").unwrap();registry.execute_plugin("goodbye").unwrap();match registry.execute_plugin("unknown") {Ok(()) => println!("执行成功"),Err(e) => println!("执行失败: {}", e),}
}fn conversion_patterns() {println!("\n=== 类型转换模式 ===");// 1. From 和 Into trait 实现from_and_into_implementations();// 2. 自定义转换方法custom_conversion_methods();// 3. 解析方法parsing_methods();
}fn from_and_into_implementations() {println!("\n=== From 和 Into 实现 ===");#[derive(Debug)]struct Point2D {x: i32,y: i32,}#[derive(Debug)]struct Point3D {x: i32,y: i32,z: i32,}// 实现 From traitimpl From<(i32, i32)> for Point2D {fn from(tuple: (i32, i32)) -> Self {Point2D {x: tuple.0,y: tuple.1,}}}impl From<Point2D> for Point3D {fn from(point: Point2D) -> Self {Point3D {x: point.x,y: point.y,z: 0,}}}// 使用 From traitlet point2d = Point2D::from((10, 20));let point3d = Point3D::from(point2d);println!("2D点: {:?}", point2d);println!("3D点: {:?}", point3d);// 使用 Into trait (自动实现)let tuple = (30, 40);let point2d: Point2D = tuple.into();let point3d: Point3D = point2d.into();println!("从元组转换的2D点: {:?}", point2d);println!("从2D点转换的3D点: {:?}", point3d);// 实现 TryFrom for fallible conversionsuse std::convert::TryFrom;impl TryFrom<Point3D> for Point2D {type Error = String;fn try_from(point: Point3D) -> Result<Self, Self::Error> {if point.z == 0 {Ok(Point2D {x: point.x,y: point.y,})} else {Err("无法转换:Z坐标不为零".to_string())}}}let point3d_zero = Point3D { x: 1, y: 2, z: 0 };let point3d_nonzero = Point3D { x: 1, y: 2, z: 3 };match Point2D::try_from(point3d_zero) {Ok(point) => println!("成功转换: {:?}", point),Err(e) => println!("转换失败: {}", e),}match Point2D::try_from(point3d_nonzero) {Ok(point) => println!("成功转换: {:?}", point),Err(e) => println!("转换失败: {}", e),}
}fn custom_conversion_methods() {println!("\n=== 自定义转换方法 ===");#[derive(Debug)]struct Celsius(f64);#[derive(Debug)]struct Fahrenheit(f64);impl Celsius {// 转换为华氏温度fn to_fahrenheit(&self) -> Fahrenheit {Fahrenheit(self.0 * 9.0 / 5.0 + 32.0)}// 从华氏温度创建fn from_fahrenheit(f: Fahrenheit) -> Self {Celsius((f.0 - 32.0) * 5.0 / 9.0)}}impl Fahrenheit {// 转换为摄氏温度fn to_celsius(&self) -> Celsius {Celsius::from_fahrenheit(*self)}// 从摄氏温度创建fn from_celsius(c: Celsius) -> Self {c.to_fahrenheit()}}let celsius = Celsius(25.0);let fahrenheit = celsius.to_fahrenheit();println!("{}°C = {}°F", celsius.0, fahrenheit.0);let back_to_celsius = fahrenheit.to_celsius();println!("{}°F = {}°C", fahrenheit.0, back_to_celsius.0);// 验证转换的正确性let boiling_c = Celsius(100.0);let boiling_f = boiling_c.to_fahrenheit();println!("水的沸点: {}°C = {}°F", boiling_c.0, boiling_f.0);let freezing_f = Fahrenheit(32.0);let freezing_c = freezing_f.to_celsius();println!("水的冰点: {}°F = {}°C", freezing_f.0, freezing_c.0);
}fn parsing_methods() {println!("\n=== 解析方法 ===");#[derive(Debug, PartialEq)]struct RGB {red: u8,green: u8,blue: u8,}impl RGB {// 从十六进制字符串解析fn from_hex(hex: &str) -> Result<Self, String> {if !hex.starts_with('#') || hex.len() != 7 {return Err("格式错误:必须是#RRGGBB格式".to_string());}let r = u8::from_str_radix(&hex[1..3], 16).map_err(|e| format!("红色分量解析错误: {}", e))?;let g = u8::from_str_radix(&hex[3..5], 16).map_err(|e| format!("绿色分量解析错误: {}", e))?;let b = u8::from_str_radix(&hex[5..7], 16).map_err(|e| format!("蓝色分量解析错误: {}", e))?;Ok(RGB { red: r, green: g, blue: b })}// 从CSS颜色名称解析fn from_name(name: &str) -> Option<Self> {match name.to_lowercase().as_str() {"red" => Some(RGB { red: 255, green: 0, blue: 0 }),"green" => Some(RGB { red: 0, green: 255, blue: 0 }),"blue" => Some(RGB { red: 0, green: 0, blue: 255 }),"white" => Some(RGB { red: 255, green: 255, blue: 255 }),"black" => Some(RGB { red: 0, green: 0, blue: 0 }),_ => None,}}// 转换为十六进制字符串fn to_hex(&self) -> String {format!("#{:02X}{:02X}{:02X}", self.red, self.green, self.blue)}// 转换为CSS rgb() 格式fn to_css_rgb(&self) -> String {format!("rgb({}, {}, {})", self.red, self.green, self.blue)}}// 测试解析方法match RGB::from_hex("#FF5733") {Ok(color) => {println!("解析的颜色: {:?}", color);println!("十六进制: {}", color.to_hex());println!("CSS格式: {}", color.to_css_rgb());},Err(e) => println!("解析错误: {}", e),}match RGB::from_name("red") {Some(color) => println!("红色: {:?}", color),None => println!("未知颜色名称"),}match RGB::from_hex("invalid") {Ok(color) => println!("颜色: {:?}", color),Err(e) => println!("解析错误: {}", e),}
}fn advanced_builder_pattern() {println!("\n=== 进阶建造者模式 ===");#[derive(Debug)]struct DatabaseConfig {host: String,port: u16,username: String,password: String,database: String,pool_size: u32,timeout: u32,ssl: bool,}// 建造者结构体struct DatabaseConfigBuilder {host: Option<String>,port: Option<u16>,username: Option<String>,password: Option<String>,database: Option<String>,pool_size: Option<u32>,timeout: Option<u32>,ssl: Option<bool>,}// 默认配置impl Default for DatabaseConfigBuilder {fn default() -> Self {DatabaseConfigBuilder {host: Some("localhost".to_string()),port: Some(5432),username: Some("postgres".to_string()),password: Some("".to_string()),database: Some("mydb".to_string()),pool_size: Some(10),timeout: Some(30),ssl: Some(false),}}}impl DatabaseConfigBuilder {fn new() -> Self {Self::default()}fn host(mut self, host: &str) -> Self {self.host = Some(host.to_string());self}fn port(mut self, port: u16) -> Self {self.port = Some(port);self}fn username(mut self, username: &str) -> Self {self.username = Some(username.to_string());self}fn password(mut self, password: &str) -> Self {self.password = Some(password.to_string());self}fn database(mut self, database: &str) -> Self {self.database = Some(database.to_string());self}fn pool_size(mut self, pool_size: u32) -> Self {self.pool_size = Some(pool_size);self}fn timeout(mut self, timeout: u32) -> Self {self.timeout = Some(timeout);self}fn ssl(mut self, ssl: bool) -> Self {self.ssl = Some(ssl);self}fn build(self) -> Result<DatabaseConfig, String> {Ok(DatabaseConfig {host: self.host.ok_or("主机名必须设置")?,port: self.port.ok_or("端口必须设置")?,username: self.username.ok_or("用户名必须设置")?,password: self.password.ok_or("密码必须设置")?,database: self.database.ok_or("数据库名必须设置")?,pool_size: self.pool_size.unwrap_or(10),timeout: self.timeout.unwrap_or(30),ssl: self.ssl.unwrap_or(false),})}}// 使用建造者模式let config = DatabaseConfigBuilder::new().host("db.example.com").port(5432).username("admin").password("secret").database("production").pool_size(20).timeout(60).ssl(true).build().unwrap();println!("数据库配置: {:?}", config);// 使用默认值let default_config = DatabaseConfigBuilder::new().build().unwrap();println!("默认配置: {:?}", default_config);
}
6.4 元组结构体进阶
6.4.1 元组结构体的高级用法
深入探索元组结构体的高级特性和使用模式。
fn advanced_tuple_structs() {println!("=== 元组结构体进阶 ===");// 1. 泛型元组结构体generic_tuple_structs();// 2. 元组结构体与模式匹配tuple_struct_pattern_matching();// 3. 元组结构体的方法实现tuple_struct_methods();// 4. 元组结构体的实际应用practical_tuple_struct_applications();
}fn generic_tuple_structs() {println!("\n=== 泛型元组结构体 ===");// 1. 基本泛型元组结构体struct Pair<T>(T, T);struct Triple<T, U, V>(T, U, V);let int_pair = Pair(1, 2);let string_pair = Pair("hello", "world");let mixed_triple = Triple(1, "hello", 3.14);println!("整数对: ({}, {})", int_pair.0, int_pair.1);println!("字符串对: ({}, {})", string_pair.0, string_pair.1);println!("混合三元组: ({}, {}, {})", mixed_triple.0, mixed_triple.1, mixed_triple.2);// 2. 泛型元组结构体方法实现impl<T> Pair<T> {fn new(first: T, second: T) -> Self {Pair(first, second)}fn first(&self) -> &T {&self.0}fn second(&self) -> &T {&self.1}fn into_tuple(self) -> (T, T) {(self.0, self.1)}}// 3. 特定类型的实现impl Pair<f64> {fn distance(&self) -> f64 {(self.0.powi(2) + self.1.powi(2)).sqrt()}}let pair = Pair::new(3.0, 4.0);println!("点({}, {})到原点的距离: {}", pair.first(), pair.second(), pair.distance());// 4. 复杂的泛型约束use std::fmt::Display;use std::ops::Add;struct DisplayablePair<T: Display, U: Display>(T, U);impl<T: Display, U: Display> DisplayablePair<T, U> {fn display(&self) {println!("显示对: ({}, {})", self.0, self.1);}}let display_pair = DisplayablePair(42, "answer");display_pair.display();// 5. 关联类型与元组结构体trait Container {type Item;fn get_item(&self) -> &Self::Item;}struct Single<T>(T);impl<T> Container for Single<T> {type Item = T;fn get_item(&self) -> &Self::Item {&self.0}}let single = Single(42);println!("单个容器: {}", single.get_item());
}fn tuple_struct_pattern_matching() {println!("\n=== 元组结构体与模式匹配 ===");// 1. 基本元组结构体struct Point(i32, i32, i32);struct Color(u8, u8, u8);let point = Point(10, 20, 30);let color = Color(255, 0, 0);// 2. 元组结构体解构let Point(x, y, z) = point;println!("解构点: x={}, y={}, z={}", x, y, z);// 3. 模式匹配中的元组结构体match point {Point(0, 0, 0) => println!("原点"),Point(x, 0, 0) => println!("在X轴上: {}", x),Point(0, y, 0) => println!("在Y轴上: {}", y),Point(0, 0, z) => println!("在Z轴上: {}", z),Point(x, y, z) => println!("在空间点: ({}, {}, {})", x, y, z),}// 4. 匹配特定值match color {Color(255, 0, 0) => println!("红色"),Color(0, 255, 0) => println!("绿色"),Color(0, 0, 255) => println!("蓝色"),Color(r, g, b) => println!("其他颜色: ({}, {}, {})", r, g, b),}// 5. 使用守卫条件match point {Point(x, y, z) if x == y && y == z => println!("在空间对角线上"),Point(x, y, z) if x > 0 && y > 0 && z > 0 => println!("在第一卦限"),Point(x, y, z) if x < 0 && y < 0 && z < 0 => println!("在第七卦限"),_ => println!("在其他位置"),}// 6. 嵌套模式匹配struct Line(Point, Point);let line = Line(Point(0, 0, 0), Point(1, 1, 1));match line {Line(Point(0, 0, 0), Point(1, 1, 1)) => println!("从原点到(1,1,1)的直线"),Line(Point(x1, y1, z1), Point(x2, y2, z2)) => {println!("从({},{},{})到({},{},{})的直线", x1, y1, z1, x2, y2, z2);}}
}fn tuple_struct_methods() {println!("\n=== 元组结构体方法实现 ===");// 1. 基本元组结构体struct Vector2D(f64, f64);struct Vector3D(f64, f64, f64);impl Vector2D {// 关联函数fn new(x: f64, y: f64) -> Self {Vector2D(x, y)}fn zero() -> Self {Vector2D(0.0, 0.0)}// 实例方法fn magnitude(&self) -> f64 {(self.0 * self.0 + self.1 * self.1).sqrt()}fn dot(&self, other: &Vector2D) -> f64 {self.0 * other.0 + self.1 * other.1}fn scale(&self, factor: f64) -> Vector2D {Vector2D(self.0 * factor, self.1 * factor)}// 消耗self的方法fn into_3d(self, z: f64) -> Vector3D {Vector3D(self.0, self.1, z)}}impl Vector3D {fn new(x: f64, y: f64, z: f64) -> Self {Vector3D(x, y, z)}fn magnitude(&self) -> f64 {(self.0 * self.0 + self.1 * self.1 + self.2 * self.2).sqrt()}fn cross(&self, other: &Vector3D) -> Vector3D {Vector3D(self.1 * other.2 - self.2 * other.1,self.2 * other.0 - self.0 * other.2,self.0 * other.1 - self.1 * other.0,)}}// 使用向量方法let v1 = Vector2D::new(3.0, 4.0);let v2 = Vector2D::new(1.0, 2.0);println!("向量1: ({}, {})", v1.0, v1.1);println!("向量1的模: {}", v1.magnitude());println!("向量1和向量2的点积: {}", v1.dot(&v2));println!("向量1缩放2倍: ({}, {})", v1.scale(2.0).0, v1.scale(2.0).1);let v3d = v1.into_3d(5.0);println!("转换为3D向量: ({}, {}, {})", v3d.0, v3d.1, v3d.2);// 3D向量运算let v3 = Vector3D::new(1.0, 0.0, 0.0);let v4 = Vector3D::new(0.0, 1.0, 0.0);let cross = v3.cross(&v4);println!("向量叉积: ({}, {}, {})", cross.0, cross.1, cross.2);
}fn practical_tuple_struct_applications() {println!("\n=== 元组结构体实际应用 ===");// 1. 错误处理中的元组结构体error_handling_with_tuple_structs();// 2. 状态机中的元组结构体state_machines_with_tuple_structs();// 3. 解析器中的元组结构体parsers_with_tuple_structs();
}fn error_handling_with_tuple_structs() {println!("\n=== 错误处理中的元组结构体 ===");// 使用元组结构体创建有意义的错误类型struct ParseError(String);struct ValidationError(String);struct NetworkError(String);enum AppError {Parse(ParseError),Validation(ValidationError),Network(NetworkError),}impl std::fmt::Display for AppError {fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {match self {AppError::Parse(ParseError(msg)) => write!(f, "解析错误: {}", msg),AppError::Validation(ValidationError(msg)) => write!(f, "验证错误: {}", msg),AppError::Network(NetworkError(msg)) => write!(f, "网络错误: {}", msg),}}}// 使用元组结构体错误fn parse_number(s: &str) -> Result<i32, ParseError> {s.parse().map_err(|_| ParseError(format!("无法解析 '{}' 为数字", s)))}fn validate_age(age: i32) -> Result<(), ValidationError> {if age < 0 {Err(ValidationError("年龄不能为负".to_string()))} else if age > 150 {Err(ValidationError("年龄不能超过150".to_string()))} else {Ok(())}}// 测试错误处理match parse_number("42") {Ok(num) => println!("解析成功: {}", num),Err(ParseError(msg)) => println!("解析失败: {}", msg),}match parse_number("abc") {Ok(num) => println!("解析成功: {}", num),Err(ParseError(msg)) => println!("解析失败: {}", msg),}match validate_age(25) {Ok(()) => println!("验证成功"),Err(ValidationError(msg)) => println!("验证失败: {}", msg),}match validate_age(200) {Ok(()) => println!("验证成功"),Err(ValidationError(msg)) => println!("验证失败: {}", msg),}
}fn state_machines_with_tuple_structs() {println!("\n=== 状态机中的元组结构体 ===");// 使用元组结构体表示状态机的不同状态// 状态标记struct Idle;struct Running;struct Paused;struct Finished;// 状态机struct Stopwatch<State> {start_time: std::time::Instant,elapsed: std::time::Duration,state: std::marker::PhantomData<State>,}impl Stopwatch<Idle> {fn new() -> Self {Stopwatch {start_time: std::time::Instant::now(),elapsed: std::time::Duration::default(),state: std::marker::PhantomData,}}fn start(self) -> Stopwatch<Running> {Stopwatch {start_time: std::time::Instant::now(),elapsed: self.elapsed,state: std::marker::PhantomData,}}}impl Stopwatch<Running> {fn pause(self) -> Stopwatch<Paused> {let elapsed = self.elapsed + self.start_time.elapsed();Stopwatch {start_time: std::time::Instant::now(),elapsed,state: std::marker::PhantomData,}}fn stop(self) -> Stopwatch<Finished> {let elapsed = self.elapsed + self.start_time.elapsed();Stopwatch {start_time: std::time::Instant::now(),elapsed,state: std::marker::PhantomData,}}fn get_elapsed(&self) -> std::time::Duration {self.elapsed + self.start_time.elapsed()}}impl Stopwatch<Paused> {fn resume(self) -> Stopwatch<Running> {Stopwatch {start_time: std::time::Instant::now(),elapsed: self.elapsed,state: std::marker::PhantomData,}}fn stop(self) -> Stopwatch<Finished> {Stopwatch {start_time: std::time::Instant::now(),elapsed: self.elapsed,state: std::marker::PhantomData,}}fn get_elapsed(&self) -> std::time::Duration {self.elapsed}}impl Stopwatch<Finished> {fn get_elapsed(&self) -> std::time::Duration {self.elapsed}fn reset(self) -> Stopwatch<Idle> {Stopwatch::new()}}// 使用状态机let stopwatch = Stopwatch::<Idle>::new();let running = stopwatch.start();// 模拟一些工作std::thread::sleep(std::time::Duration::from_millis(100));let paused = running.pause();println!("经过时间: {:?}", paused.get_elapsed());let running_again = paused.resume();std::thread::sleep(std::time::Duration::from_millis(50));let finished = running_again.stop();println!("总时间: {:?}", finished.get_elapsed());let idle_again = finished.reset();// 现在可以重新开始
}fn parsers_with_tuple_structs() {println!("\n=== 解析器中的元组结构体 ===");// 使用元组结构体构建解析器组合子struct Parser<I, O>(Box<dyn Fn(I) -> Result<(O, I), String>>);impl<I, O> Parser<I, O> whereI: Clone,{fn new<F>(parser: F) -> Self whereF: Fn(I) -> Result<(O, I), String> + 'static,{Parser(Box::new(parser))}fn parse(&self, input: I) -> Result<(O, I), String> {(self.0)(input)}// 映射解析结果fn map<U, F>(self, f: F) -> Parser<I, U>whereF: Fn(O) -> U + 'static,{Parser::new(move |input| {self.parse(input).map(|(result, remaining)| (f(result), remaining))})}// 组合两个解析器fn and_then<U, F>(self, f: F) -> Parser<I, U>whereF: Fn(O) -> Parser<I, U> + 'static,{Parser::new(move |input| {let (result1, remaining1) = self.parse(input)?;f(result1).parse(remaining1)})}}// 创建一些基本解析器fn char_parser(c: char) -> Parser<&str, char> {Parser::new(move |input: &str| {if input.starts_with(c) {Ok((c, &input[1..]))} else {Err(format!("期望 '{}', 找到 '{}'", c, input.chars().next().unwrap_or(' ')))}})}fn digit_parser() -> Parser<&str, u32> {Parser::new(|input: &str| {if let Some(c) = input.chars().next() {if let Some(digit) = c.to_digit(10) {return Ok((digit, &input[1..]));}}Err("期望数字".to_string())})}fn string_parser(s: &str) -> Parser<&str, String> {let expected = s.to_string();Parser::new(move |input: &str| {if input.starts_with(s) {Ok((expected.clone(), &input[s.len()..]))} else {Err(format!("期望 '{}'", s))}})}// 使用解析器let hello_parser = string_parser("Hello");let world_parser = string_parser("World");match hello_parser.parse("Hello World") {Ok((result, remaining)) => {println!("解析结果: '{}', 剩余: '{}'", result, remaining);match world_parser.parse(remaining.trim_start()) {Ok((result2, remaining2)) => {println!("第二次解析结果: '{}', 剩余: '{}'", result2, remaining2);},Err(e) => println!("第二次解析失败: {}", e),}},Err(e) => println!("解析失败: {}", e),}// 测试数字解析器match digit_parser().parse("123abc") {Ok((digit, remaining)) => {println!("解析的数字: {}, 剩余: '{}'", digit, remaining);},Err(e) => println!("数字解析失败: {}", e),}// 组合解析器let hello_world_parser = string_parser("Hello").and_then(|_| string_parser(" World"));match hello_world_parser.parse("Hello World") {Ok((result, remaining)) => {println!("组合解析结果: '{}', 剩余: '{}'", result, remaining);},Err(e) => println!("组合解析失败: {}", e),}
}
通过本章的全面学习,你已经深入掌握了Rust中结构体和方法的各个方面。从基础的结构体定义到高级的关联函数模式,从简单的方法语法到复杂的设计模式应用,你现在应该能够熟练地使用结构体和方法来组织数据和行为了。在下一章中,我们将探讨枚举与模式匹配,这是Rust中另一个强大的特性。
