跳到主要内容

策略模式

问题

Rust 中如何实现策略模式?

答案

Rust 有两种实现方式:trait 对象(动态分发)和闭包(函数式风格)。

方式 1:Trait(推荐)

trait Compressor {
fn compress(&self, data: &[u8]) -> Vec<u8>;
fn name(&self) -> &str;
}

struct Gzip;
struct Zstd;

impl Compressor for Gzip {
fn compress(&self, data: &[u8]) -> Vec<u8> {
// gzip 压缩逻辑
data.to_vec()
}
fn name(&self) -> &str { "gzip" }
}

impl Compressor for Zstd {
fn compress(&self, data: &[u8]) -> Vec<u8> {
// zstd 压缩逻辑
data.to_vec()
}
fn name(&self) -> &str { "zstd" }
}

// 静态分发(编译时确定策略)
fn process<C: Compressor>(compressor: &C, data: &[u8]) -> Vec<u8> {
compressor.compress(data)
}

// 动态分发(运行时选择策略)
fn process_dynamic(compressor: &dyn Compressor, data: &[u8]) -> Vec<u8> {
println!("使用 {} 压缩", compressor.name());
compressor.compress(data)
}

方式 2:闭包(简单场景)

fn sort_users(users: &mut Vec<User>, strategy: impl Fn(&User, &User) -> std::cmp::Ordering) {
users.sort_by(strategy);
}

// 使用
sort_users(&mut users, |a, b| a.name.cmp(&b.name)); // 按名字
sort_users(&mut users, |a, b| b.age.cmp(&a.age)); // 按年龄降序

trait vs 闭包选择

维度Trait闭包
状态可以有字段捕获环境
多个方法❌(通常单方法)
可命名
复杂策略推荐不推荐

常见面试问题

Q1: Rust 的策略模式和 Java/Go 有什么不同?

答案

Rust 独特之处在于可以选择静态分发(零成本)或动态分发

  • 泛型 <C: Compressor> → 编译时确定,零开销
  • Trait Object &dyn Compressor → 运行时确定,有 vtable 开销

Java/Go 只有动态分发(接口方法都是虚调用)。

相关链接