4.2 方法与关联函数

在 Rust 中,结构体本身只包含数据,不直接包含行为。要为结构体(或其他类型)添加方法或函数,需要使用 impl 块(implementation block)。通过 impl,你可以定义方法(method)和关联函数(associated function),从而将数据与操作逻辑组织在一起。

定义方法

方法是与特定类型关联的函数,其第一个参数通常是 self&self&mut self,表示调用该方法的实例。

例如,为之前定义的 Point 结构体添加一个计算到原点距离的方法:

struct Point {
    x: f64,
    y: f64,
}

impl Point {
    fn distance_from_origin(&self) -> f64 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}

这里,&selfself: &Point 的简写,表示该方法借用当前实例进行只读访问。调用方式如下:

let p = Point { x: 3.0, y: 4.0 };
println!("Distance: {}", p.distance_from_origin()); // 输出 5.0

如果方法需要修改实例,则使用 &mut self

impl Point {
    fn move_by(&mut self, dx: f64, dy: f64) {
        self.x += dx;
        self.y += dy;
    }
}

let mut p = Point { x: 0.0, y: 0.0 };
p.move_by(1.0, 2.0);

也可以使用 self(无引用)来获取实例的所有权,通常用于消耗性操作或转换:

impl Point {
    fn to_tuple(self) -> (f64, f64) {
        (self.x, self.y)
    }
}

调用后,原变量将不再可用。

关联函数

关联函数是定义在 impl 块中但不以 self 作为参数的函数。它们类似于其他语言中的“静态方法”,常用于构造实例。

最常见的例子是 new 函数:

impl Point {
    fn new(x: f64, y: f64) -> Point {
        Point { x, y }
    }
}

调用时使用类型名而非实例:

let p = Point::new(1.0, 2.0);

Rust 标准库中的许多类型都提供 new 或其他构造函数(如 String::fromVec::with_capacity 等)。

为同一类型定义多个 impl 块

Rust 允许为同一个类型编写多个 impl 块,这在组织代码或条件编译时很有用:

impl Point {
    fn x(&self) -> f64 {
        self.x
    }
}

impl Point {
    fn y(&self) -> f64 {
        self.y
    }
}

虽然通常建议将相关方法放在同一个 impl 块中以提高可读性,但语法上是允许分散的。

小结

通过 impl 块,Rust 将数据(结构体)与行为(方法和关联函数)清晰地关联起来,同时保持所有权和借用规则的一致性。方法使你可以安全地操作实例数据,而关联函数则提供了灵活的构造方式。这种设计既支持面向对象风格的编程,又保留了函数式和系统级编程的灵活性,是 Rust 类型系统的重要组成部分。

#Rust 入门教程 分享于 1 周前

内容由 AI 创作和分享,仅供参考