我正在针对要实现的容器类型进行单元测试:
#[test]
fn test_get_mut_normal_tail() -> Result<(), ListError> {
let mut actual_list: ArrayList<u64> = ArrayList::new();
let expected_list: ArrayList<u64> = ArrayList {
elems: vec![1, 2, 3, 8],
};
actual_list.append(1)?;
actual_list.append(2)?;
actual_list.append(3)?;
actual_list.append(4)?;
let actual_res: Result<&mut u64, ListError> = actual_list.get_mut(3);
let expected_res: Result<&mut u64, ListError> = Ok(&mut 4);
let elem = actual_res.unwrap();
*elem *= 2;
assert_eq!(actual_list, expected_list);
assert_eq!(actual_res, expected_res);
Ok(())
}
但是,
rustc
提示:error[E0382]: borrow of moved value: `actual_res`
--> src\arraylist.rs:358:9
|
351 | let actual_res: Result<&mut u64, ListError> = actual_list.get_mut(3);
| ---------- move occurs because `actual_res` has type `std::result::Result<&mut u64, list::ListError>`, which does not implement the `Copy` trait
...
354 | let elem = actual_res.unwrap();
| ---------- value moved here
...
358 | assert_eq!(actual_res, expected_res);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
我不明白,因为the
Result
docs表示Result
实现Copy
(只要所包含的两种类型也都可以)。显然&mut u64
实现了Copy
,而我的ListError
类型derive
也实现了它:#[derive(Clone, Copy, PartialEq, Debug)]
pub enum ListError {
OutOfBounds,
Impossible,
}
ArrayList::get_mut()
的代码在此处(如果相关):fn get_mut(&mut self, pos: usize) -> Result<&mut T, ListError> {
if pos >= self.elems.len() { /* bounds check */
return Err(ListError::OutOfBounds);
}
match self.elems.get_mut(pos) {
Some(elem) => Ok(elem),
None => Err(ListError::OutOfBounds)
}
}
总而言之,我有两个问题:
最佳答案
&mut u64
实际上并未实现复制。 &mut T
无法实现复制,以防止同时创建多个可变借位。
引用文档:https://doc.rust-lang.org/std/primitive.reference.html#trait-implementations
在1的答案中,您可以通过使用assert_eq!(elem, 4);
而不是assert_eq!(actual_res, expected_res);
来纠正错误。或者,您可以使用Result::map
修改并返回新结果
let actual_res: Result<&mut u64, ListError> = actual_list.get_mut(3).map(|elem| {
*elem *= 2;
elem
};
关于unit-testing - 当 `Result`不是 `Copy`时,设计单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59832570/