方法与关联函数
> 学习 impl 块定义方法,理解实例方法(&self)与关联函数(无 self)的区别。
结构体与方法
impl 块基础
rust
▶ Run#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
// 实例方法(第一个参数是&self)
fn area(&self) -> u32 {
self.width * self.height
}
// 另一个实例方法
fn perimeter(&self) -> u32 {
2 * (self.width + self.height)
}
}
fn main() {
let rect = Rectangle {
width: 30,
height: 50,
};
println!("面积:{}", rect.area());
println!("周长:{}", rect.perimeter());
println!("调试输出:{:?}", rect);
}self 的三种形式
rust
▶ Runstruct Data {
value: i32,
}
impl Data {
// &self - 不可变借用(最常用)
fn print(&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 data = Data { value: 42 };
data.print(); // 借用,data 仍可用
data.increment(); // 可变借用,修改值
let value = data.into_value(); // 移动,data 不再可用
// data.print(); // ❌ 错误:data 已移动
}带参数的方法
rust
▶ Run#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
// 方法接受另一个结构体实例
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
// 可变方法
fn double_size(&mut self) {
self.width *= 2;
self.height *= 2;
}
}
fn main() {
let rect1 = Rectangle { width: 100, height: 50 };
let rect2 = Rectangle { width: 50, height: 30 };
println!("rect1 能否容纳 rect2: {}", rect1.can_hold(&rect2));
let mut rect3 = rect2;
rect3.double_size();
println!("翻倍后:{:?}", rect3);
}关联函数(构造函数)
new 函数
rust
▶ Run#[derive(Debug)]
struct User {
username: String,
email: String,
active: bool,
}
impl User {
// 关联函数(没有 self 参数)
fn new(username: String, email: String) -> Self {
Self {
username,
email,
active: true,
}
}
// 带默认值的构造函数
fn with_defaults(username: String) -> Self {
Self {
username,
email: String::from("unknown@example.com"),
active: true,
}
}
fn print_info(&self) {
println!("用户:{} ({})", self.username, self.email);
}
}
fn main() {
let user1 = User::new(
String::from("alice"),
String::from("alice@example.com"),
);
let user2 = User::with_defaults(String::from("bob"));
user1.print_info();
user2.print_info();
}多个构造函数
rust
▶ Run#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
// 标准构造函数
fn new(width: u32, height: u32) -> Self {
Self { width, height }
}
// 正方形
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
// 从元组创建
fn from_tuple((w, h): (u32, u32)) -> Self {
Self {
width: w,
height: h,
}
}
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect1 = Rectangle::new(10, 20);
let rect2 = Rectangle::square(15);
let rect3 = Rectangle::from_tuple((5, 10));
println!("rect1 面积:{}", rect1.area());
println!("rect2 面积:{}", rect2.area());
println!("rect3 面积:{}", rect3.area());
}小结
impl Struct { }定义方法,可以有多个 impl 块- 实例方法:
&self(只读)、&mut self(可变)、self(消耗) - 关联函数:无 self 参数,用于构造函数(如
new) - 调用:
instance.method()方法,Struct::function()关联函数
练习题
详见:练习题
---
## 多个 impl 块
```rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
// 第一个 impl 块
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
// 第二个 impl 块
impl Rectangle {
fn perimeter(&self) -> u32 {
2 * (self.width + self.height)
}
fn is_square(&self) -> bool {
self.width == self.height
}
}
// 第三个 impl 块(可以用于条件编译)
#[cfg(debug_assertions)]
impl Rectangle {
fn debug_print(&self) {
println!("[DEBUG] Rectangle: {}x{}", self.width, self.height);
}
}
fn main() {
let rect = Rectangle { width: 10, height: 20 };
println!("面积:{}", rect.area());
println!("周长:{}", rect.perimeter());
println!("是正方形:{}", rect.is_square());
#[cfg(debug_assertions)]
rect.debug_print();
}