在尝试将Vec<u8>
发送给期望&[u8]
的函数的不同方法时,我犯了一个实际有效的“错误”。我写了一些示例代码来说明这一点:
fn sum(v: &[u8]) -> u8 {
let mut s = 0u8;
for x in v.iter() {
s = s + x;
}
return s;
}
fn main() {
let myarr = [1u8, 2u8, 3u8];
let myvec = vec![1u8, 2u8, 3u8];
println!("{}", sum(&myarr));
println!("{}", sum(&myvec));
}
我对此有几个问题:
答案 0 :(得分:6)
让我们放开一件事:sum
函数中有无数组。 Rust有三种相关类型,您可以在此处搜索Stack Overflow或 The Rust Programming Language 以获取有关它们的更多信息:
&[T]
。Vec<T>
[T; n]
v
参数是 slice ,它只是指向一大块数据和元素数量的指针。
为什么以及如何运作?这两种类型之间是否有自动投射?
Deref
trait在这里发挥作用。这个特征的实现如下:
impl<T> Deref for Vec<T> {
type Target = [T];
fn deref(&self) -> &[T];
}
这意味着对Vec<T>
的任何引用都可以作为对[T]
的引用,并从目标类型中获取所有方法。编译器可以理解Deref
,但任何类型都可以实现它,因此它只是特殊的。
它是否会受到任何惩罚,或者只是占用了向量的底层数组的内存位置?
这是零成本转换,这就是编译器为您做的原因。让编译器为你做任何昂贵的事情是非常不寻常的。
这是否意味着对于这种类型的使用,最好使用数组而不是向量作为API?
绝对!您有百分之百的时间接受&[T]
而不是&Vec<T>
。除了Vec
之外,更多的事情可以提供&[T]
,而数组就是一个例子。
答案 1 :(得分:3)