在 Rust 中,方法(methods)是与特定类型关联的函数,定义在 impl(implementation)块中。方法提供了面向对象编程的特性,同时保持了 Rust 的安全性和所有权原则。
1. 方法基础
定义和调用方法
rust
struct Rectangle {
width: u32,
height: u32,
}
// impl 块为 Rectangle 定义方法
impl Rectangle {
// 关联函数(类似静态方法) - 没有 self 参数
fn new(width: u32, height: u32) -> Self {
Rectangle { width, height }
}
// 实例方法 - 不可变引用 self
fn area(&self) -> u32 {
self.width * self.height
}
// 实例方法 - 可变引用 self
fn scale(&mut self, factor: u32) {
self.width *= factor;
self.height *= factor;
}
// 实例方法 - 获取所有权 self
fn consume(self) -> (u32, u32) {
(self.width, self.height)
}
}
fn main() {
// 使用关联函数创建实例
let mut rect = Rectangle::new(10, 20);
// 调用实例方法
println!("面积: {}", rect.area()); // 200
// 调用可变方法
rect.scale(2);
println!("缩放后面积: {}", rect.area()); // 800
// 调用消费方法
let dimensions = rect.consume();
println!("尺寸: {:?}", dimensions); // (20, 40)
// rect 在这里不再可用,因为所有权已被消费
}
2. self 参数的三种形式
&self - 不可变借用
rust
struct Circle {
radius: f64,
}
impl Circle {
// 只读方法,不需要修改结构体
fn circumference(&self) -> f64 {
2.0 * std::f64::consts::PI * self.radius
}
fn diameter(&self) -> f64 {
2.0 * self.radius
}
// 可以在不可变方法中调用其他不可变方法
fn describe(&self) -> String {
format!("半径: {:.2}, 直径: {:.2}, 周长: {:.2}",
self.radius, self.diameter(), self.circumference())
}
}
fn main() {
let circle = Circle { radius: 5.0 };
println!("{}", circle.describe());
}
&mut self - 可变借用
rust
struct Counter {
value: i32,
max: i32,
}
impl Counter {
// 可变方法,需要修改结构体字段
fn increment(&mut self) -> i32 {
if self.value < self.max {
self.value += 1;
}
self.value
}
fn decrement(&mut self) -> i32 {
if self.value > 0 {
self.value -= 1;
}
self.value
}
// 可变方法可以调用不可变方法
fn increment_with_check(&mut self) -> bool {
let old_value = self.value;
self.increment();
old_value != self.value
}
}
fn main() {
let mut counter = Counter { value: 0, max: 10 };
for _ in 0..12 {
if counter.increment_with_check() {
println!("递增成功: {}", counter.value);
} else {
println!("达到最大值: {}", counter.value);
break;
}
}
}
self - 获取所有权
rust
struct Resource {
data: String,
id: u32,
}
impl Resource {
// 获取所有权的方法,通常用于转移资源或清理
fn take_data(self) -> String {
println!("资源 {} 被消费", self.id);
self.data
}
// 转换方法:消费 self,返回新类型
fn into_tuple(self) -> (u32, String) {
(self.id, self.data)
}
// 链式消费方法
fn with_prefix(mut self, prefix: &str) -> Self {
self.data = format!("{}{}", prefix, self.data);
self
}
}
fn main() {
let resource = Resource {
data: "重要数据".to_string(),
id: 1,
};
// 方法链
let transformed = resource
.with_prefix("前缀: ")
.with_prefix("[标记] ");
let data = transformed.take_data();
println!("获取的数据: {}", data); // [标记] 前缀: 重要数据
}
3. 关联函数
关联函数(associated functions)类似于其他语言中的静态方法,不接收 self 参数。
rust
struct Point {
x: f64,
y: f64,
}
impl Point {
// 关联函数 - 创建新实例的常用方式
fn origin() -> Self {
Point { x: 0.0, y: 0.0 }
}
fn new(x: f64, y: f64) -> Self {
Point { x, y }
}
// 工厂方法模式
fn from_polar(radius: f64, angle: f64) -> Self {
Point {
x: radius * angle.cos(),
y: radius * angle.sin(),
}
}
// 类型转换关联函数
fn from_tuple((x, y): (f64, f64)) -> Self {
Point { x, y }
}
}
fn main() {
let p1 = Point::origin();
let p2 = Point::new(3.0, 4.0);
let p3 = Point::from_polar(5.0, std::f64::consts::FRAC_PI_4);
let p4 = Point::from_tuple((1.0, 2.0));
println!("原点: ({:.2}, {:.2})", p1.x, p1.y);
println!("直角坐标: ({:.2}, {:.2})", p2.x, p2.y);
println!("极坐标: ({:.2}, {:.2})", p3.x, p3.y);
}
4. 方法链(Method Chaining)
rust
struct Builder {
value: String,
count: u32,
flag: bool,
}
impl Builder {
fn new() -> Self {
Builder {
value: String::new(),
count: 0,
flag: false,
}
}
// 每个方法返回 &mut Self 以实现链式调用
fn set_value(&mut self, value: &str) -> &mut Self {
self.value = value.to_string();
self
}
fn set_count(&mut self, count: u32) -> &mut Self {
self.count = count;
self
}
fn set_flag(&mut self, flag: bool) -> &mut Self {
self.flag = flag;
self
}
fn build(&self) -> String {
format!("值: {}, 计数: {}, 标志: {}",
self.value, self.count, self.flag)
}
}
// 使用 Self 返回类型实现更优雅的链式调用
struct Config {
timeout: u32,
retries: u32,
debug: bool,
}
impl Config {
fn new() -> Self {
Config {
timeout: 30,
retries: 3,
debug: false,
}
}
fn timeout(mut self, timeout: u32) -> Self {
self.timeout = timeout;
self
}
fn retries(mut self, retries: u32) -> Self {
self.retries = retries;
self
}
fn debug(mut self, debug: bool) -> Self {
self.debug = debug;
self
}
fn display(&self) {
println!("超时: {}s, 重试: {}次, 调试: {}",
self.timeout, self.retries, self.debug);
}
}
fn main() {
// 第一种链式调用
let builder = Builder::new()
.set_value("test")
.set_count(42)
.set_flag(true);
println!("{}", builder.build());
// 第二种链式调用(更常用)
let config = Config::new()
.timeout(60)
.retries(5)
.debug(true);
config.display();
}
5. 泛型方法
rust
struct Container<T> {
value: T,
}
impl<T> Container<T> {
// 泛型关联函数
fn new(value: T) -> Self {
Container { value }
}
// 泛型方法 - 不可变引用
fn get_value(&self) -> &T {
&self.value
}
// 泛型方法 - 可变引用
fn set_value(&mut self, value: T) {
self.value = value;
}
// 带有泛型约束的方法
fn print_if_displayable(&self)
where
T: std::fmt::Display,
{
println!("值: {}", self.value);
}
}
// 实现特定类型的额外方法
impl Container<String> {
fn length(&self) -> usize {
self.value.len()
}
fn append(&mut self, suffix: &str) {
self.value.push_str(suffix);
}
}
// 为特定 trait 实现方法
trait Processable {
fn process(&self);
}
impl<T: Processable> Container<T> {
fn process_value(&self) {
self.value.process();
}
}
fn main() {
let mut container = Container::new(42);
println!("值: {}", container.get_value());
container.set_value(100);
container.print_if_displayable();
let mut str_container = Container::new("Hello".to_string());
println!("长度: {}", str_container.length());
str_container.append(", World!");
println!("新值: {}", str_container.get_value());
}
6. 常量方法(const 方法)
Rust 支持在编译时计算的方法,使用 const fn 关键字。
基本 const 方法
rust
struct Math {
value: i32,
}
impl Math {
// const 关联函数 - 可以在编译时调用
const fn new(value: i32) -> Self {
Math { value }
}
// const 方法 - 可以在编译时执行
const fn square(&self) -> i32 {
self.value * self.value
}
// const 方法也可以返回新实例
const fn with_offset(&self, offset: i32) -> Math {
Math { value: self.value + offset }
}
// 注意:const fn 中有严格限制,不能使用运行时特性
// 以下代码会编译错误:
// const fn invalid() -> String {
// String::from("hello") // 分配内存,不允许在 const 上下文中
// }
}
// 在常量上下文中使用 const 方法
const MATH_CONST: Math = Math::new(5);
const SQUARED: i32 = MATH_CONST.square(); // 编译时计算
const OFFSET_MATH: Math = MATH_CONST.with_offset(10);
fn main() {
println!("平方: {}", SQUARED); // 25
println!("偏移值: {}", OFFSET_MATH.value); // 15
// 运行时也可以使用
let math = Math::new(7);
println!("运行时平方: {}", math.square()); // 49
}
const 泛型方法
rust
struct ArrayWrapper<const N: usize> {
data: [i32; N],
}
impl<const N: usize> ArrayWrapper<N> {
// const 泛型方法
const fn new() -> Self {
ArrayWrapper { data: [0; N] }
}
// 获取长度 - 编译时常量
const fn len(&self) -> usize {
N
}
// 编译时初始化
const fn filled_with(value: i32) -> Self {
let mut data = [value; N];
// 可以在 const fn 中进行简单计算
if N > 0 {
data[0] = value * 2;
}
ArrayWrapper { data }
}
}
fn main() {
const WRAPPER: ArrayWrapper<5> = ArrayWrapper::new();
println!("长度: {}", WRAPPER.len()); // 5
const FILLED: ArrayWrapper<3> = ArrayWrapper::filled_with(10);
println!("填充数组: {:?}", FILLED.data); // [20, 10, 10]
// 运行时使用
let runtime_wrapper = ArrayWrapper::<10>::new();
println!("运行时长度: {}", runtime_wrapper.len());
}
const trait 实现
rust
#![feature(const_trait_impl)] // 需要 nightly Rust
// 定义 const trait
trait ConstMath {
const fn add(&self, other: i32) -> i32;
const fn is_positive(&self) -> bool;
}
struct Number {
value: i32,
}
impl const ConstMath for Number {
// 实现 const trait 方法
const fn add(&self, other: i32) -> i32 {
self.value + other
}
const fn is_positive(&self) -> bool {
self.value > 0
}
}
fn main() {
const NUM: Number = Number { value: 42 };
const SUM: i32 = NUM.add(8); // 编译时计算
const IS_POS: bool = NUM.is_positive();
println!("和: {}", SUM); // 50
println!("是否正数: {}", IS_POS); // true
}
7. 闭包作为方法
Rust 允许在结构体中存储闭包,并为其实现方法。
存储闭包字段
rust
struct Processor<F>
where
F: Fn(i32) -> i32,
{
processor: F,
name: String,
}
impl<F> Processor<F>
where
F: Fn(i32) -> i32,
{
// 创建带有闭包的实例
fn new(name: &str, processor: F) -> Self {
Processor {
processor,
name: name.to_string(),
}
}
// 调用存储的闭包
fn process(&self, value: i32) -> i32 {
(self.processor)(value)
}
// 链式处理:组合多个处理器
fn then<G>(self, other: Processor<G>) -> Processor<impl Fn(i32) -> i32>
where
G: Fn(i32) -> i32,
{
Processor::new(
&format!("{} -> {}", self.name, other.name),
move |x| other.process(self.process(x))
)
}
}
fn main() {
// 创建处理器
let doubler = Processor::new("doubler", |x| x * 2);
let incrementer = Processor::new("incrementer", |x| x + 1);
let squarer = Processor::new("squarer", |x| x * x);
// 使用单个处理器
println!("加倍: {}", doubler.process(5)); // 10
// 链式组合处理器
let pipeline = doubler.then(incrementer).then(squarer);
println!("流水线结果: {}", pipeline.process(3)); // (3*2+1)^2 = 49
}
闭包 trait 对象
rust
struct CallbackBox {
callback: Box<dyn Fn(i32) -> i32>,
count: u32,
}
impl CallbackBox {
fn new<F>(callback: F) -> Self
where
F: Fn(i32) -> i32 + 'static,
{
CallbackBox {
callback: Box::new(callback),
count: 0,
}
}
// 调用闭包并记录调用次数
fn call(&mut self, value: i32) -> i32 {
self.count += 1;
(self.callback)(value)
}
fn get_count(&self) -> u32 {
self.count
}
// 动态修改闭包
fn set_callback<F>(&mut self, callback: F)
where
F: Fn(i32) -> i32 + 'static,
{
self.callback = Box::new(callback);
self.count = 0; // 重置计数器
}
}
fn main() {
let mut processor = CallbackBox::new(|x| x * 2);
println!("第一次调用: {}", processor.call(5)); // 10
println!("第二次调用: {}", processor.call(10)); // 20
println!("调用次数: {}", processor.get_count()); // 2
// 动态更换闭包
processor.set_callback(|x| x + 100);
println!("新闭包调用: {}", processor.call(5)); // 105
println!("调用次数重置: {}", processor.get_count()); // 1
}
闭包方法的高级用法
rust
use std::collections::HashMap;
struct FunctionRegistry {
functions: HashMap<String, Box<dyn Fn(i32) -> i32>>,
}
impl FunctionRegistry {
fn new() -> Self {
FunctionRegistry {
functions: HashMap::new(),
}
}
// 注册闭包
fn register<F>(&mut self, name: &str, func: F)
where
F: Fn(i32) -> i32 + 'static,
{
self.functions.insert(name.to_string(), Box::new(func));
}
// 调用注册的函数
fn call(&self, name: &str, value: i32) -> Option<i32> {
self.functions.get(name).map(|f| f(value))
}
// 组合多个函数
fn compose(&self, names: &[&str]) -> Option<Box<dyn Fn(i32) -> i32>> {
if names.is_empty() {
return None;
}
let mut functions = Vec::new();
for name in names {
if let Some(func) = self.functions.get(*name) {
// 需要克隆闭包的引用
functions.push(func as &dyn Fn(i32) -> i32);
} else {
return None;
}
}
Some(Box::new(move |x| {
let mut result = x;
for func in &functions {
result = func(result);
}
result
}))
}
}
fn main() {
let mut registry = FunctionRegistry::new();
// 注册各种函数
registry.register("double", |x| x * 2);
registry.register("increment", |x| x + 1);
registry.register("square", |x| x * x);
registry.register("negate", |x| -x);
// 调用单个函数
if let Some(result) = registry.call("double", 5) {
println!("double(5) = {}", result); // 10
}
// 组合函数
if let Some(composed) = registry.compose(&["double", "increment", "square"]) {
println!("组合结果: {}", composed(3)); // ((3*2)+1)^2 = 49
}
}
8. 闭包和方法的交互
方法返回闭包
rust
struct Multiplier {
factor: i32,
}
impl Multiplier {
// 方法返回闭包,闭包捕获 self
fn get_multiplier(&self) -> impl Fn(i32) -> i32 + '_ {
// 闭包借用 self
move |x| x * self.factor
}
// 返回 move 闭包,获取 factor 的所有权
fn into_multiplier(self) -> impl Fn(i32) -> i32 {
let factor = self.factor;
move |x| x * factor
}
// 返回带条件的闭包
fn get_conditional_multiplier(&self, threshold: i32) -> impl Fn(i32) -> i32 + '_ {
move |x| {
if x > threshold {
x * self.factor
} else {
x
}
}
}
}
fn main() {
let multiplier = Multiplier { factor: 3 };
// 获取借用闭包
let multiply_by_3 = multiplier.get_multiplier();
println!("乘3: {}", multiply_by_3(5)); // 15
// 获取条件闭包
let conditional = multiplier.get_conditional_multiplier(10);
println!("条件乘: {}", conditional(5)); // 5 (不大于10)
println!("条件乘: {}", conditional(15)); // 45 (大于10)
// 获取所有权闭包
let owned_multiplier = multiplier.into_multiplier();
println!("所有权闭包: {}", owned_multiplier(7)); // 21
}
闭包调用对象方法
rust
struct Calculator {
base: i32,
}
impl Calculator {
fn add(&self, x: i32) -> i32 {
self.base + x
}
fn multiply(&self, x: i32) -> i32 {
self.base * x
}
// 创建处理流水线
fn create_pipeline(&self) -> Vec<Box<dyn Fn(i32) -> i32>> {
vec![
Box::new(move |x| self.add(x)),
Box::new(move |x| self.multiply(x)),
Box::new(|x| x * 2), // 独立闭包
]
}
}
fn main() {
let calc = Calculator { base: 10 };
// 直接调用方法
println!("加: {}", calc.add(5)); // 15
println!("乘: {}", calc.multiply(3)); // 30
// 通过闭包调用方法
let add_closure = |x: i32| calc.add(x);
println!("闭包加: {}", add_closure(5)); // 15
// 使用流水线
let pipeline = calc.create_pipeline();
let mut result = 5;
for func in pipeline {
result = func(result);
}
println!("流水线结果: {}", result); // ((10+5)*10)*2 = 300
}
9. 闭包作为 trait 实现
rust
// 定义可调用 trait
trait Operation {
fn execute(&self, x: i32) -> i32;
// 默认实现:组合操作
fn then(self, other: impl Operation) -> Composed<Self, impl Operation>
where
Self: Sized,
{
Composed::new(self, other)
}
}
// 为闭包实现 Operation trait
impl<F> Operation for F
where
F: Fn(i32) -> i32,
{
fn execute(&self, x: i32) -> i32 {
self(x)
}
}
// 组合操作的结构体
struct Composed<A, B> {
first: A,
second: B,
}
impl<A, B> Composed<A, B> {
fn new(first: A, second: B) -> Self {
Composed { first, second }
}
}
impl<A, B> Operation for Composed<A, B>
where
A: Operation,
B: Operation,
{
fn execute(&self, x: i32) -> i32 {
let intermediate = self.first.execute(x);
self.second.execute(intermediate)
}
}
fn main() {
// 闭包自动实现 Operation trait
let double = |x| x * 2;
let increment = |x| x + 1;
let square = |x| x * x;
// 使用 trait 方法
println!("加倍: {}", double.execute(5)); // 10
println!("递增: {}", increment.execute(5)); // 6
// 链式组合
let pipeline = double.then(increment).then(square);
println!("组合操作: {}", pipeline.execute(3)); // ((3*2)+1)^2 = 49
// 也可以组合自定义操作
struct CustomOp;
impl Operation for CustomOp {
fn execute(&self, x: i32) -> i32 {
x * 10
}
}
let custom_pipeline = double.then(CustomOp);
println!("自定义组合: {}", custom_pipeline.execute(4)); // (4*2)*10 = 80
}
10. 闭包的生命周期和方法
rust
struct DataProcessor<'a> {
data: &'a [i32],
processor: Box<dyn Fn(&[i32]) -> i32 + 'a>,
}
impl<'a> DataProcessor<'a> {
fn new<F>(data: &'a [i32], processor: F) -> Self
where
F: Fn(&[i32]) -> i32 + 'a,
{
DataProcessor {
data,
processor: Box::new(processor),
}
}
fn process(&self) -> i32 {
(self.processor)(self.data)
}
// 返回新的 DataProcessor,改变处理逻辑
fn with_processor<F>(self, processor: F) -> DataProcessor<'a>
where
F: Fn(&[i32]) -> i32 + 'a,
{
DataProcessor {
data: self.data,
processor: Box::new(processor),
}
}
}
fn main() {
let data = vec![1, 2, 3, 4, 5];
// 创建处理器
let sum_processor = DataProcessor::new(&data, |slice| slice.iter().sum());
println!("求和: {}", sum_processor.process()); // 15
// 更换处理器
let max_processor = sum_processor.with_processor(|slice| {
*slice.iter().max().unwrap_or(&0)
});
println!("最大值: {}", max_processor.process()); // 5
// 更复杂的处理器
let complex_processor = max_processor.with_processor(|slice| {
let sum: i32 = slice.iter().sum();
let count = slice.len() as i32;
if count > 0 { sum / count } else { 0 }
});
println!("平均值: {}", complex_processor.process()); // 3
}
11. 实际应用示例
配置驱动的处理器
rust
struct ConfigurableProcessor {
transformations: Vec<Box<dyn Fn(i32) -> i32>>,
}
impl ConfigurableProcessor {
fn new() -> Self {
ConfigurableProcessor {
transformations: Vec::new(),
}
}
// 添加变换
fn add_transformation<F>(&mut self, transform: F)
where
F: Fn(i32) -> i32 + 'static,
{
self.transformations.push(Box::new(transform));
}
// 处理数据
fn process(&self, mut value: i32) -> i32 {
for transform in &self.transformations {
value = transform(value);
}
value
}
// 从配置创建处理器
fn from_config(config: &ProcessorConfig) -> Self {
let mut processor = Self::new();
if config.double {
processor.add_transformation(|x| x * 2);
}
if config.increment {
processor.add_transformation(|x| x + config.increment_by);
}
if config.square {
processor.add_transformation(|x| x * x);
}
processor
}
}
struct ProcessorConfig {
double: bool,
increment: bool,
increment_by: i32,
square: bool,
}
fn main() {
let config = ProcessorConfig {
double: true,
increment: true,
increment_by: 5,
square: true,
};
let processor = ConfigurableProcessor::from_config(&config);
let result = processor.process(3);
println!("配置处理结果: {}", result); // ((3*2)+5)^2 = 121
}
事件驱动的回调系统
rust
struct EventEmitter {
listeners: Vec<Box<dyn Fn(&str)>>,
}
impl EventEmitter {
fn new() -> Self {
EventEmitter {
listeners: Vec::new(),
}
}
// 添加事件监听器
fn add_listener<F>(&mut self, listener: F)
where
F: Fn(&str) + 'static,
{
self.listeners.push(Box::new(listener));
}
// 触发事件
fn emit(&self, event: &str) {
println!("触发事件: {}", event);
for listener in &self.listeners {
listener(event);
}
}
// 带过滤器的监听器
fn add_filtered_listener<F>(&mut self, filter: &'static str, action: F)
where
F: Fn(&str) + 'static,
{
self.add_listener(move |event| {
if event.contains(filter) {
action(event);
}
});
}
}
fn main() {
let mut emitter = EventEmitter::new();
// 添加普通监听器
emitter.add_listener(|event| {
println!("监听器1收到: {}", event);
});
// 添加过滤监听器
emitter.add_filtered_listener("error", |event| {
println!("错误事件处理: {}", event);
});
emitter.add_filtered_listener("info", |event| {
println!("信息事件处理: {}", event);
});
// 触发事件
emitter.emit("系统启动");
emitter.emit("发生错误: 文件不存在");
emitter.emit("信息: 处理完成");
}
闭包和方法在 Rust 中紧密配合,提供了强大的抽象能力。闭包可以捕获环境变量,方法可以为类型提供组织良好的接口。结合使用它们可以创建灵活、可复用的代码结构。