スライシングでの表現(@Rust)

Beginning Rustからのコードですが、変数というのはある型の表現のaliasというのはRustでも言えることですが、そこから以下のrange = 2..5のような定義もできます。2..5のように表現される形式の型は、

std::ops::Range

になります。

https://doc.rust-lang.org/std/ops/struct.Range.html

さらに発展系とも言えますが、&[23, 17, 12, 16, 15, 2][2..5]のような表現も順序立てて見てみると有効になることがわかります。

最後の1行はその直前の4行と等価ですが、なぜ最後の1行のような表現ができるかがわかるプロセスそのものになっています。

fn main() {
    fn min(arr: &[i32]) -> i32 {
        // Let's assume 'arr' is not empty.
        let mut minimum = arr[0];
        for i in 1..arr.len() {
            if arr[i] < minimum { minimum = arr[i]; }
        }
        minimum
    }

    let arr = [23, 17, 12, 16, 15, 2];
    let range = 2..5;                       // a variable can accepts like "2..5"
    let slice_ref = &arr[range];
    print!("{}\n", min(slice_ref));

    // &[23, 17, 12, 16, 15, 2] is as &arr
    // &[23, 17, 12, 16, 15, 2][2..5] is as &arr[range]
    print!("same as above : {}", min(&[23, 17, 12, 16, 15, 2][2..5])); 
}

蛇足ながら、なぜスライス(可変長)を引数とするときには参照でなければならないかというと、コンパイル時に長さが決まっていないといけないから、他の型でも全てそうですが。本質的に引数や戻り値はスタック上で固定長で管理されるので、可変(任意)長では管理できないからという理屈です。

上記のコード例ではarrはサイズが可変長なので参照を使い、minimumはサイズが既知で固定なので戻り値として使用できることになります。

 

admin

 

カテゴリーRust