Rust中如何将单个可变对象传入函数的多个参数?
解决方案
你不需要修改原有spin函数的签名,只需要调整测试用模拟对象的实现方式即可,核心思路是把模拟对象的共享状态抽离,用内部可变性容器包裹,拆分出独立的Timer和Motor模拟实例,两者共享同一个状态即可。
具体实现步骤
1. 引入内部可变性容器,抽离共享状态
把原来DummyTimerMotor里的公共状态单独拆成结构体,用Rc<RefCell<>>包裹实现多所有者、运行时可变借用:
use std::cell::RefCell; use std::rc::Rc; // 抽离的共享模拟状态 #[derive(Default)] struct MockState { is_on: bool, time_high: u64, } // 独立的模拟计时器实现 struct DummyTimer { state: Rc<RefCell<MockState>>, } impl Timer for DummyTimer { fn reset(&mut self) {} fn wait_microseconds(&mut self, duration: u64) { let mut state = self.state.borrow_mut(); if state.is_on { state.time_high += duration; } } } // 独立的模拟电机实现 struct DummyMotor { state: Rc<RefCell<MockState>>, } impl Motor for DummyMotor { fn set_step_high(&mut self) { self.state.borrow_mut().is_on = true; } fn set_step_low(&mut self) { self.state.borrow_mut().is_on = false; } }
2. 测试时传入两个独立的模拟实例
两个模拟实例背后共享同一个状态,既符合spin函数接收两个独立参数的要求,又能正常统计高电平时长:
fn main() { // 初始化共享状态 let shared_state = Rc::new(RefCell::new(MockState::default())); // 生成独立的计时器、电机模拟实例 let mut dummy_timer = DummyTimer { state: shared_state.clone() }; let mut dummy_motor = DummyMotor { state: shared_state.clone() }; // 调用原有spin函数,完全不需要修改 spin(&mut dummy_timer, &mut dummy_motor); // 读取统计结果,输出为500000 println!("The 'step' pin was HIGH for {} microseconds", shared_state.borrow().time_high); }
方案说明
- 完全保留原有
spin函数的设计,不需要修改业务代码,计时器和电机的逻辑依然是完全独立的 - 仅调整测试用模拟对象的实现,利用Rust的内部可变性绕过同一对象双重可变借用的限制,仅在测试场景引入额外开销,不会影响生产环境代码的性能
- 逻辑符合直觉:测试场景下我们本来就需要让计时器和电机的模拟状态联动,共享状态是合理的设计
内容的提问来源于stack exchange,提问作者Sophie Swett
相关产品推荐
相关产品推荐

