それは安全にこれを実行することは可能ではありません。理由を理解するには、これらのタイプの実装方法を理解することが重要です。配列はN個の初期化された要素を持つことが保証されています。より小さくても大きくすることはできません。コンパイル時には、これらの保証によって配列のサイズ面が削除され、配列はN * sizeof(要素)の空間しか占めません。 [T; N]
と[T; M]
はさまざまな種類があることを意味
(ときN
!= M
)、あなたが他の1つの参照を変換することはできません。
慣用溶液の代わりスライスを使用することである。
fn foo(array: &[u32; 10]) -> &[u32] {
&array[0..5]
}
スライスは、このように時間を実行するためにコンパイル時から、そのロジックを移動、データとデータの長さへのポインタを含みます。 誰かは、この危険な道を行うことになるでしょう
ので、私はコンパイルしが正しい出力を生成するためにを見えるコードを提示します。私は実際に安全か正しいのか分かりません。
use std::mem;
fn foo(array: &[u32; 10]) -> &[u32; 5] {
unsafe {
let data = array.as_ptr();
mem::transmute(data.offset(3))
}
}
fn main() {
let input = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let output = foo(&input);
println!("{:?}", output);
}
初期オフセットは関数で発生しますが、長さはそうではありません。これは型システムでエンコードされています。 は、返された値の終わりが定義されたメモリの末尾に来るようにオフセットを指定することによって、簡単にクラッシュを引き起こすことができます()。
代わりにスライス(または新しい配列インスタンス)を指定する必要があります。 AFAIKは、借用されたスライスを安全に借用配列に変換することはできません。 –
長さはタイプすなわち'' fn foo(array:&[u32; 10)) - >&[u32] {&array [0..5]} 'のように、スライスを返さなければならないと思っていますが、 '&[u32; 10' – Lee