ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Rust教程-4.2 方法

Rust教程-4.2 方法 4.2 方法方法Method是与结构体或其他自定义类型关联的函数。它们定义在impl块中允许你为自定义类型赋予特定的行为从而实现数据与行为的封装。Rust 中的方法分为两类实例方法与具体实例绑定和关联函数与类型本身绑定最常见的就是new构造函数。4.2.1 在结构体上定义方法要为一个结构体定义方法需要使用implimplementation关键字。在impl块内定义的函数其第一个参数必须是某种形式的self这样它才能成为实例方法并通过点号.语法在实例上调用。示例为 Rectangle 结构体定义方法struct Rectangle { width: u32, height: u32, } impl Rectangle { // 定义一个实例方法 area fn area(self) - u32 { self.width * self.height } // 定义另一个实例方法 can_hold fn can_hold(self, other: Rectangle) - bool { self.width other.width self.height other.height } } fn main() { let rect1 Rectangle { width: 30, height: 50 }; let rect2 Rectangle { width: 10, height: 40 }; // 通过点号语法调用方法 println!(rect1 的面积是: {} 平方像素, rect1.area()); println!(rect1 能容纳 rect2 吗? {}, rect1.can_hold(rect2)); }方法 vs 普通函数调用方式不同方法使用instance.method()的点号语法调用而普通函数使用function()直接调用。自动引用Rust 会根据方法的self参数类型自动为实例添加引用、可变引用mut或直接取得所有权。你不需要在调用时手动写rect1。语义更清晰方法明确表达了这个行为属于这个类型使代码更具可读性和组织性。多个impl块Rust 允许为同一个类型定义多个impl块。这在大型项目中很有用可以将不同功能的方法分组或者将方法的定义和 trait 实现分开。impl Rectangle { fn area(self) - u32 { self.width * self.height } } impl Rectangle { fn perimeter(self) - u32 { 2 * (self.width self.height) } }4.2.2 self 参数方法的第一个参数决定了该方法如何拥有或借用调用它的实例。Rust 提供了三种self参数的形式每种对应不同的所有权语义形式含义对实例的影响使用场景self不可变借用实例保持不变可继续使用只读取数据不修改mut self可变借用可以修改实例的字段需要修改实例的数据self取得所有权实例被消耗调用后原变量失效需要消耗或转换实例示例三种 self 参数的对比#[derive(Debug)] struct Counter { value: i32, } impl Counter { // self不可变借用只读取 fn display(self) { println!(当前值: {}, self.value); } // mut self可变借用可以修改 fn increment(mut self) { self.value 1; } // self取得所有权消耗实例 fn into_value(self) - i32 { self.value } } fn main() { let mut counter Counter { value: 0 }; counter.display(); // 使用 selfcounter 之后仍可使用 counter.increment(); // 使用 mut selfcounter 之后仍可使用 println!({:?}, counter); // counter 仍然有效 let val counter.into_value(); // 使用 selfcounter 的所有权被转移 // counter.display(); // 编译错误counter 已被消耗不再有效 println!(最终值: {}, val); }选择哪种 self 的指导原则优先使用self如果方法不需要修改实例这是最安全、最灵活的选择。需要修改时使用mut self当方法需要改变实例的状态时。谨慎使用self只在确实需要消耗实例时使用例如将实例转换为另一种类型或实现类似into_value这样的消费并返回模式。4.2.3 关联函数关联函数是定义在impl块中但不以self作为参数的函数。它们不属于任何具体的实例而是属于类型本身。最常见的关联函数是构造函数new用于创建并返回类型的新实例。关联函数通过双冒号::语法调用而不是点号语法。示例定义和调用关联函数struct Rectangle { width: u32, height: u32, } impl Rectangle { // 关联函数没有 self 参数通常用作构造函数 fn new(width: u32, height: u32) - Rectangle { Rectangle { width, height } } // 另一个关联函数创建正方形 fn square(size: u32) - Rectangle { Rectangle { width: size, height: size, } } // 实例方法对比 fn area(self) - u32 { self.width * self.height } } fn main() { // 通过 :: 语法调用关联函数 let rect Rectangle::new(30, 50); let sq Rectangle::square(10); // 通过 . 语法调用实例方法 println!(矩形面积: {}, rect.area()); println!(正方形面积: {}, sq.area()); }关联函数的特点无 self 参数这是区分关联函数和实例方法的关键标志。命名空间关联函数通常用于提供与类型相关的工具函数或工厂方法。常见命名约定new()— 最常用的构造函数名。from_xxx()— 从某种特定数据创建实例如from_str()。default()— 创建具有默认值的实例。with_xxx()— 创建实例并设置某些特定属性如with_capacity()。一个类型可以有多个关联函数它们为创建实例提供了不同的途径使 API 更加灵活和直观。impl Rectangle { fn new(width: u32, height: u32) - Self { Self { width, height } } fn from_diameter(diameter: u32) - Self { Self { width: diameter, height: diameter, } } fn unit_square() - Self { Self::new(1, 1) } }Self类型别名在impl块中Self是当前类型的别名。在上面的例子中Self等价于Rectangle。使用Self可以让代码更简洁也便于将来重构时减少修改量。
返回列表