此函数返回类似列表的集合的第一个元素。它适用于各种不同的列表类型:
fn first<T: Copy>(x: impl Deref<Target=[T]>) -> T {
x[0]
}
例如,它编译并运行:
let data: Vec<usize> = vec![3, 4];
assert_eq!(first(data), 3);
let data: &[usize] = &[3, 4];
assert_eq!(first(data), 3);
let data: Rc<[usize]> = Rc::new([3, 4]);
assert_eq!(first(data), 3);
它还编译并运行:
fn stub(x: &[usize]) -> usize {
first(x)
}
let data: &[usize; 2] = &[3, 4];
assert_eq!(stub(data), 3);
assert_eq!(stub(&[3, 4]), 3);
但这无法编译:
let data: &[usize; 2] = &[3, 4];
assert_eq!(first(data), 3); // Fails.
assert_eq!(first(&[3, 4]), 3); // Fails.
错误消息是:
type mismatch resolving `<&[usize; 2] as std::ops::Deref>::Target == [_]`
我想我明白发生了什么。每种类型
T
有一种独特的类型
<T as Deref>::Target
. 什么时候
T
是
&[usize; 2]
[usize; 2]
不
[usize]
. 编译器能够强制
&[T; 2]
到
&[T]
let
或
stub()
,但如果我不这样做,那么就无法确定是否需要强制。
但这令人沮丧。对于人类来说,失败的调用的目的是什么是显而易见的,编译器也知道需要做什么
Vec<usize>
Box<[usize]>
,
Rc<[usize]>
,
&[usize]
也
first()
所以最后两个电话也能用?如果没有,是否有语法要求编译器强制
&[使用;2]
到
&[使用]
即
不用
允许
?
Playground
.