run*_*ter 26 arrays coercion slice rust
为什么都是&[u8]
和&[u8; 3]
确定在这个例子吗?
fn main() {
let x: &[u8] = &[1u8, 2, 3];
println!("{:?}", x);
let y: &[u8; 3] = &[1u8, 2, 3];
println!("{:?}", y);
}
Run Code Online (Sandbox Code Playgroud)
&[T; n]
可以胁迫的事实&[T]
是使它们可以容忍的方面. - 克里斯摩根
为什么可以&[T; n]
胁迫&[T]
?在其他条件下,这种强制发生了吗?
Chr*_*gan 27
[T; n]
是一个长度数组n
,表示为n
相邻T
实例.
&[T; n]
纯粹是对该数组的引用,表示为指向数据的精简指针.
[T]
是一个切片,一个未分级的类型; 它只能通过某种形式的间接使用.
&[T]
称为切片,是一种大小的类型.它是一个胖指针,表示为指向第一个项目和切片长度的指针.
因此,阵列在编译时已知其长度,而切片长度是运行时问题.数组是目前Rust中的二等公民,因为不可能形成数组泛型.有各种性状的手动实现[T; 0]
,[T; 1]
,& C.,通常最多32; 由于这种限制,切片通常更有用.&[T; n]
可以胁迫的事实&[T]
是使它们可以容忍的方面.
还有的实现fmt::Debug
了[T; 3]
,其中T
工具Debug
,另一个是&T
地方T
工具fmt::Debug
,并且使得u8
器具Debug
,&[u8; 3]
也不会.
为什么可以
&[T; n]
胁迫&[T]
?在Rust,强制何时发生?
它会在需要时强制执行,而且不会在其他时间强制执行.我可以想到两个案例:
&[T]
你给它一个&[T; n]
它会默默地胁迫;x.starts_with(…)
给[T; n]
它时会发现没有这样的方法[T; n]
,所以autoref进入游戏并尝试&[T; n]
,这没有帮助,然后强制发挥作用,它尝试&[T]
,它有一个方法调用starts_with
.该片段[1, 2, 3].starts_with(&[1, 2])
演示了两者.
ken*_*ytm 11
为什么可以
&[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>
(以及一些使编译工作更容易的条件)(Ptr<X>
如果它实现,Rust会识别为"指针类型" CoerceUnsized
.实际规则表示为" 如果T: CoerceUnsized<U>
然后T
强制执行U
".)
&[T; n]
强制要求的原因&[T]
是规则4:(a)编译器impl Unsize<[T]> for [T; n]
为每个生成实现[T; n]
,(b)引用&X
是指针类型.使用这些,&[T; n]
可以胁迫&[T]
.
ker*_*520 10
我根据 kennytm 和 Chris Morgan 的回答创建了这张图片。它描述了各种概念: