この例で&[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]
_が_&[T]
_に強制できるのはなぜですか?
もう1つの答えは、_&[T; n]
_shouldが_&[T]
_に強制変換される理由を説明しています。ここでは、コンパイラがその_&[T; n]
_canは_&[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
_はderef()
メソッドを介して_&U
_に強制変換しますT: DerefMut
_の場合、_&mut T
_はderef_mut()
を介して_&mut U
_に強制変換されます)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は、_Ptr<X>
_を実装する場合、「ポインタ型」として認識します CoerceUnsized
。実際のルールは、「if _T: CoerceUnsized<U>
_次にT
はU
"に強制変換します。)
_&[T; n]
_が_&[T]
_に強制変換される理由は、ルール4です。(a)コンパイラーはすべての_impl Unsize<[T]> for [T; n]
_に対して実装_[T; n]
_を生成し、(b)参照_&X
_ポインタ型です。これらを使用して、_&[T; n]
_canは_&[T]
_に強制変換できます。