为什么此示例中的&[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]
的事实是使它们可以容忍的方面。 — Chris Morgan
为什么&[T; n]
可以强制&[T]
?在其他条件下,这种强制发生了吗?
答案 0 :(得分:24)
[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]
也是如此。
为什么
&[T]
可以强制&[T; n]
?在Rust,强制何时发生?
它会在需要时强制执行,而且不会在其他时间执行。我可以想到两个案例:
x.starts_with(…)
并且你给它[T; n]
它会默默地强制执行; [T; n]
上致电&[T; n]
时,会发现&[T]
上没有此类方法,因此autoref开始播放并尝试starts_with
,没有帮助,然后强制发挥作用,它会尝试[1, 2, 3].starts_with(&[1, 2])
,它有一个名为tbl <- prop.table(table(counts1))
left <- -0.4 + do.call('seq', as.list(range(counts1)))
right <- left + (2 * 0.4)
bottom <- rep(0, length(left))
top <- tbl
xlim <- c(-0.5, 0.5) + range(counts1)
nf <- layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(3,1))
par(mar=c(3.1, 3.1, 1.1, 2.1))
plot(NA, xlim=xlim, ylim=c(0, max(tbl)))
rect(left, bottom, right, top, col='gray')
boxplot(counts1, horizontal=TRUE, outline=TRUE, ylim=xlim, frame=F, width = 10)
的方法。代码段dh $@
演示了两者。
答案 1 :(得分:9)
为什么
&[T; n]
可以强制&[T]
?
另一个答案解释了为什么&[T; n]
应该强制&[T]
,这里我将解释编译器如何解决&[T; n]
可以强制执行&[T]
。
有four possible coercions in Rust:
传递性。
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
是&#34;指针类型&#34; (例如&T
,*mut T
,Box
,Rc
等)和T: Unsize<U>
,然后Ptr<T>
强制Ptr<U>
。< / p>
Unsize
特征会自动实现:
[T; n]: Unsize<[T]>
T: Unsize<Trait>
其中T: Trait
struct Foo<…> { …, field: T }: Unsize< struct Foo<…> { …, field: U }>
,前提是T: Unsize<U>
(以及一些使编译工作更轻松的条件)(Rust将Ptr<X>
识别为&#34;指针类型&#34;如果它实现CoerceUnsized
。实际规则表示为“ if {{1}然后T: CoerceUnsized<U>
强迫T
“。)
U
强制&[T; n]
的原因是规则4:(a)编译器为每个&[T]
生成实现impl Unsize<[T]> for [T; n]
,以及(b)引用{{ 1}}是指针类型。使用这些,[T; n]
可以强制&X
。
答案 2 :(得分:0)