unit-testing - 当`Result`不是`Copy`时设计单元测试
问题描述
我对正在实施的容器类型进行了单元测试:
#[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)
我不明白,因为文档表明实现了Result
(只要包含的两种类型也都这样做)。清楚地实现和我的类型它也: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
};
推荐阅读
- python - ValueError:不允许负尺寸错误?
- flutter - Flutter:是否有可能将按钮值发送到文本字段?
- node.js - 谷歌工作表 api nodejs
- android - 如何在颤振上创建这样的卡片?
- python - ValueError:输入包含 NaN、无穷大或对于 dtype('float64') 来说太大的值。如何处理这个错误?
- elasticsearch - Elasticsearch 7.x 搜索空闲慢
- vue.js - 如何将本地文件夹图像(资产)包含到 vue App
- php - php中如何格式化数组
- mysql - ubuntu 18.04 LTS 中未连接 SQL
- javascript - Javascript ES6 更好的方法来循环对象并与多个嵌套对象匹配并返回 id