You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Car结构体对象传入自定义Fn类型的get_energy函数作为创建参数?

实现方案

当然可以实现,你可以通过在Car结构体中存储闭包(或函数)来实现不同车型的能量获取逻辑。下面提供两种常见的实现方式:

方式一:使用泛型存储具体闭包类型

这种方式让Car结构体持有具体的闭包类型,每个不同的闭包会生成不同的Car实例类型,适合不需要统一类型的场景:

// 定义Car结构体,泛型F代表闭包类型,要求实现Fn() trait
struct Car<F>
where
    F: Fn(),
{
    get_energy: F,
}

impl<F> Car<F>
where
    F: Fn(),
{
    // 构造函数,接收闭包作为参数
    fn new(get_energy: F) -> Self {
        Car { get_energy }
    }

    // 调用存储的闭包执行能量获取逻辑
    fn run_get_energy(&self) {
        (self.get_energy)();
    }
}

// 模拟特斯拉的能量获取步骤
fn grab_cable() {
    println!("抓取充电电缆");
}

fn insert_cable() {
    println!("插入充电接口");
}

fn pass_electricity() {
    println!("开始传输电力");
}

// 模拟本田的能量获取步骤
fn open_fuel_tank() {
    println!("打开油箱盖");
}

fn fill_fuel() {
    println!("加注燃油");
}

fn close_fuel_tank() {
    println!("关闭油箱盖");
}

fn main() {
    // 创建特斯拉实例,传入对应的闭包
    let tesla = Car::new(|| {
        grab_cable();
        insert_cable();
        pass_electricity();
    });
    tesla.run_get_energy();

    // 创建本田实例,传入另一个闭包
    let honda = Car::new(|| {
        open_fuel_tank();
        fill_fuel();
        close_fuel_tank();
    });
    honda.run_get_energy();
}

方式二:使用Trait Object统一类型

如果需要让不同车型的Car实例属于同一类型(比如放在同一个集合里),可以用Box<dyn Fn()>来存储闭包:

// 定义Car结构体,使用Box<dyn Fn()>存储闭包
struct Car {
    get_energy: Box<dyn Fn()>,
}

impl Car {
    // 构造函数,接收闭包并装箱
    fn new(get_energy: impl Fn() + 'static) -> Self {
        Car {
            get_energy: Box::new(get_energy),
        }
    }

    fn run_get_energy(&self) {
        (self.get_energy)();
    }
}

// 同样的步骤函数
fn grab_cable() { println!("抓取充电电缆"); }
fn insert_cable() { println!("插入充电接口"); }
fn pass_electricity() { println!("开始传输电力"); }
fn open_fuel_tank() { println!("打开油箱盖"); }
fn fill_fuel() { println!("加注燃油"); }
fn close_fuel_tank() { println!("关闭油箱盖"); }

fn main() {
    let tesla = Car::new(|| {
        grab_cable();
        insert_cable();
        pass_electricity();
    });
    let honda = Car::new(|| {
        open_fuel_tank();
        fill_fuel();
        close_fuel_tank();
    });

    // 可以把不同车型放在同一个Vec里
    let cars: Vec<Car> = vec![tesla, honda];
    for car in cars {
        car.run_get_energy();
        println!("---");
    }
}

补充说明

  • 若闭包需要捕获外部变量,要注意生命周期问题:泛型方式下闭包的生命周期会和Car实例绑定;Trait Object方式下闭包需满足'static生命周期(也可调整结构体的生命周期标注适配)。
  • 你也可以定义Trait规范能量获取行为,让不同车型实现该Trait,但闭包的方式更直接贴合你“创建时传入函数”的需求。

内容的提问来源于stack exchange,提问作者WiseEye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 21:55:20