提问人:runrioter 提问时间:6/12/2015 最后编辑:Shepmasterrunrioter 更新时间:11/12/2023 访问量:10411
切片和数组有什么区别?
What is the difference between a slice and an array?
问:
为什么在这个例子中两者都是好的?&[u8]
&[u8; 3]
fn main() {
let x: &[u8] = &[1u8, 2, 3];
println!("{:?}", x);
let y: &[u8; 3] = &[1u8, 2, 3];
println!("{:?}", y);
}
可以胁迫的事实是使他们可以容忍的方面。— 克里斯·摩根
&[T; n]
&[T]
为什么可以胁迫?这种胁迫发生在什么其他情况下?&[T; n]
&[T]
答:
[T; n]
是一个长度的数组,表示为相邻的实例。n
n
T
&[T; n]
纯粹是对该数组的引用,表示为指向数据的细指针。
[T]
是一个切片,一个未调整大小的类型;它只能通过某种形式的间接使用。
&[T]
,称为切片,是一种大小类型。它是一个胖指针,表示为指向第一项和切片长度的指针。
因此,数组的长度在编译时是已知的,而切片长度是运行时的问题。数组目前在 Rust 中是二等公民,因为不可能形成数组泛型。有 、 、 &c. 的各种特征的手动实现,通常最多 32 个;由于此限制,切片通常更有用。可以胁迫的事实是使他们可以容忍的方面。[T; 0]
[T; 1]
&[T; n]
&[T]
有一个 for where implements 的实现,另一个 for where implements 的实现,以及 so as implements 的实现。fmt::Debug
[T; 3]
T
Debug
&T
T
fmt::Debug
u8
Debug
&[u8; 3]
为什么可以胁迫?在 Rust 中,强制何时发生?
&[T; n]
&[T]
它会在需要时强制执行,而不是在其他任何时候。我能想到两种情况:
- 如果某物期待一个,而你给它一个,它就会默默地胁迫;
&[T]
&[T; n]
- 当你调用 时,它会观察到 上没有这样的方法,所以 autoref 开始发挥作用,它尝试 ,这无济于事,然后强制开始发挥作用,它尝试 ,它有一个叫做 的方法。
x.starts_with(…)
[T; n]
[T; n]
&[T; n]
&[T]
starts_with
该代码段演示了这两者。[1, 2, 3].starts_with(&[1, 2])
评论
FnMut(char) -> bool
[char; N]
&[char; N]
impl<const N: usize>
为什么可以胁迫?
&[T; n]
&[T]
另一个答案解释了为什么应该强制到,在这里我将解释编译器如何工作,可以强制到。&[T; n]
&[T]
&[T; n]
&[T]
传递。
- 如果胁迫 和 胁迫 ,则 胁迫 。
T
U
U
V
T
V
- 如果胁迫 和 胁迫 ,则 胁迫 。
指针减弱:
- 消除可变性:→和→
&mut T
&T
*mut T
*const T
- 转换为原始指针:→和→
&mut T
*mut T
&T
*const T
- 消除可变性:→和→
-
- 如果 ,则强制通过方法
T: Deref<Target = U>
&T
&U
deref()
- (类似地,如果 ,则强制通过
T: DerefMut
&mut T
&mut U
deref_mut()
)
- 如果 ,则强制通过方法
-
如果是“指针类型”(例如、、等),则 ,则强制为 。
Ptr
&T
*mut T
Box
Rc
T: Unsize<U>
Ptr<T>
Ptr<U>
该特征自动实现:
Unsize
[T; n]: Unsize<[T]>
T: Unsize<Trait>
哪里T: Trait
struct Foo<…> { …, field: T }: Unsize< struct Foo<…> { …, field: U }>
,前提是(以及更多条件,使编译器的工作更容易)T: Unsize<U>
(如果 Rust 实现了
CoerceUnsized
,则将其识别为“指针类型”。实际规则表述为,“如果T: CoerceUnsized<U>
则T
强制到U
”。Ptr<X>
强制执行的原因是规则 4:(a) 编译器为每个 生成实现,并且 (b) 引用是指针类型。使用这些,可以强制 .&[T; n]
&[T]
impl Unsize<[T]> for [T; n]
[T; n]
&X
&[T; n]
&[T]
我根据 kennytm 和 Chris Morgan 的回答创作了这张照片。它描述了各种概念:
评论
n
内存中不存在。对于切片,它位于胖指针中,但对于数组或数组引用,它仅存在于类型中,如 ;这一切都在编译时整理出来,根本不会在运行时出现。N
上一个:Sns 条形图不对切片值进行排序
下一个:切片和数组有什么区别?
评论