如何为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
相关产品推荐
相关产品推荐

