我有以下代码:
struct HeadTail<T>(T, Vec<T>);
fn head_tail<T : Clone>(v: &Vec<T>) -> Option<HeadTail<T>> {
match v.len() {
0 => None,
_ => {
let mut tmp_v = v.clone();
let head = tmp_v.remove(0);
Some(HeadTail(head, tmp_v))
}
}
}
#[test]
fn head_tail_many() {
let vec = vec![1, 2, 3, 4];
let result = head_tail(&vec);
match result {
None => unreachable!(),
Some(HeadTail(head, tail)) => {
assert_eq!(1, head);
assert_eq!(3, tail.len());
assert_eq!([2, 3, 4], tail);
}
};
}
Run Code Online (Sandbox Code Playgroud)
并且它失败并出现以下异常:
<std macros>:5:8: 5:33 error: the trait `core::cmp::PartialEq<collections::vec::Vec<_>>` is not implemented for the type `[_; 3]` [E0277]
<std macros>:5 if ! ( * left_val == * right_val ) {
Run Code Online (Sandbox Code Playgroud)
为什么Rust在这种情况下不能推断类型?
我该怎么做让它知道它是任何数字类型(例如u8)?
在调试这些类型的事物时创建MCVE很有用.这是一个例子:
fn main() {
let vec = vec![1, 2, 3, 4];
assert_eq!([1,2,3,4], vec);
}
Run Code Online (Sandbox Code Playgroud)
随着错误
<std macros>:5:8: 5:33 error: the trait `core::cmp::PartialEq<collections::vec::Vec<_>>` is not implemented for the type `[_; 4]` [E0277]
<std macros>:5 if ! ( * left_val == * right_val ) {
^~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
所以,有一些错误PartialEq,让我们尝试进一步减少:
fn main() {
let vec = vec![1, 2, 3, 4];
[1,2,3,4] == vec;
}
Run Code Online (Sandbox Code Playgroud)
有相同的基本错误:
<anon>:3:5: 3:21 error: the trait `core::cmp::PartialEq<collections::vec::Vec<_>>` is not implemented for the type `[_; 4]` [E0277]
<anon>:3 [1,2,3,4] == vec;
^~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
的_在Vec<_>指一个尚未-破坏型.让我们使用显式类型来查看是否存在问题:
fn main() {
let vec = vec![1u8, 2, 3, 4];
[1u8,2,3,4] == vec;
}
Run Code Online (Sandbox Code Playgroud)
不,还是一样的错误:
<anon>:3:5: 3:23 error: the trait `core::cmp::PartialEq<collections::vec::Vec<u8>>` is not implemented for the type `[u8; 4]` [E0277]
<anon>:3 [1u8,2,3,4] == vec;
^~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
让我们尝试翻转一下:
fn main() {
let vec = vec![1u8, 2, 3, 4];
vec == [1u8,2,3,4];
}
Run Code Online (Sandbox Code Playgroud)
嗯.这有效!交换原始代码中的顺序也有效.
当然,剩下的大问题是为什么.让我们看看文档Vec,特别是关于PartialEq以下部分:
impl<'a, 'b, A, B> PartialEq<[B; 4]> for Vec<A>
where A: PartialEq<B>
{
fn eq(&self, other: &[B; 4]) -> bool { ... }
}
Run Code Online (Sandbox Code Playgroud)
因此,如果可以测试和平等,则可以测试a Vec<A>到&[B; 4]for的相等性.反过来呢?数组的文档根本没有提到(这是有道理的,因为它们更像是一个核心特性),并且没有任何反向实现.这当然看起来令人惊讶,我没有很好的解释为什么他们不在那里......ABVecPartialEq
啊,看来这发生在这次提交中.这是提交消息:
丢失的主要实施是比较
&[T]和Vec<T>(按此顺序)的能力.此更改还修改
assert_eq!宏以不考虑两个相等的方向,只有左/右形式给出的宏.这种修改的动机是由于&[T] == Vec<T>不再编译,导致标准库中的单元测试中出现数百个错误(并且可能在整个社区中也是如此).
Manishearth发现了一篇全面的博客文章,详细描述了这一变化背后的基本原理!
| 归档时间: |
|
| 查看次数: |
382 次 |
| 最近记录: |