[英]What is the difference between a slice and an array?
為什么兩個&[u8]
和&[u8; 3]
&[u8; 3]
這個例子好嗎?
fn main() {
let x: &[u8] = &[1u8, 2, 3];
println!("{:?}", x);
let y: &[u8; 3] = &[1u8, 2, 3];
println!("{:?}", y);
}
&[T; n]
&[T; n]
可以強迫&[T]
是使它們可以容忍的方面。 - 克里斯摩根
為什么可以&[T; n]
&[T; n]
強迫&[T]
? 在其他條件下,這種強制發生了嗎?
[T; n]
[T; n]
是長度的數組n
,表示為n
相鄰T
實例。
&[T; n]
&[T; n]
純粹是對該數組的引用,表示為指向數據的精簡指針。
[T]
是切片,未分類型; 它只能通過某種形式的間接使用。
&[T]
,稱為切片,是一種大小的類型。 它是一個胖指針 ,表示為指向第一個項目和切片長度的指針。
因此,陣列在編譯時已知其長度,而切片長度是運行時問題。 數組是目前Rust中的二等公民,因為不可能形成數組泛型。 有[T; 0]
的各種特征的手動實現[T; 0]
[T; 0]
, [T; 1]
[T; 1]
, &c。 ,通常最多32; 由於這種限制,切片通常更有用。 &[T; n]
&[T; n]
可以強迫&[T]
是使它們可以容忍的方面。
對於[T; 3]
有一個fmt::Debug
的實現[T; 3]
[T; 3]
其中T
實現Debug
,另一個用於&T
,其中T
實現fmt::Debug
,因此u8
實現Debug
, &[u8; 3]
&[u8; 3]
也是。
為什么可以
&[T; n]
&[T; n]
強迫&[T]
? 在Rust,強制何時發生?
它會在需要時強制執行,而且不會在其他時間強制執行。 我可以想到兩個案例:
&[T]
,你給它一個&[T; n]
&[T; n]
它會悄悄脅迫; [T; n]
上調用x.starts_with(…)
時 [T; n]
它會觀察到[T; n]
[T; n]
,所以autoref發揮作用,它嘗試&[T; n]
&[T; n]
,這沒有幫助,然后強制發揮作用,它嘗試&[T]
,它有一個名為starts_with
的方法。 代碼片段[1, 2, 3].starts_with(&[1, 2])
演示了兩者。
為什么可以
&[T; n]
&[T; n]
強迫&[T]
?
另一個答案解釋了為什么&[T; n]
&[T; n]
應該強制到&[T]
,在這里我將解釋編譯器如何解決&[T; n]
&[T; n]
可以強迫&[T]
。
及物。
T
強迫U
和U
強制為V
,則T
強制為V
指針弱化:
&mut T
→ &T
和*mut T
→ *const T
&mut T
→ *mut T
和&T
→ *const T
Deref
特質 :
T: Deref<Target = U>
,則&T
通過deref()
方法deref()
為&U
. T: DerefMut
,則&mut T
通過deref_mut()
為&mut U
) Unsize
特質 :
如果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>
(還有一些條件可以使編譯工作更輕松) (如果它實現了CoerceUnsized
Rust會將Ptr<X>
識別為“指針類型”。實際規則表示為“ 如果T: CoerceUnsized<U>
則T
T: CoerceUnsized<U>
為U
”。)
原因&[T; n]
&[T; n]
強制執行&[T]
是規則4:(a)編譯器impl Unsize<[T]> for [T; n]
生成實現impl Unsize<[T]> for [T; n]
impl Unsize<[T]> for [T; n]
每一個[T; n]
[T; n]
和(b)引用&X
是指針類型。 使用這些, &[T; n]
&[T; n]
可以強迫&[T]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.