スライス型
Rustではスライス型を[T]
もしくは&[T]
と表現するらしいです。
[i32]
とはi32
型のスライス型となります。
Vectorをスライス型にする
Vectorをスライス型にする方法は複数あります。
こちらのVectorをスライス型にしていきます。
let v = vec![1, 2, 3];
as_slice()メソッド
Vectorのas_slicceメソッドを使います。
型は&[T]
となります。
let v_slice: &[i32] = v.as_slice();
参照外し(dereferencing)
参照じゃないのに参照外し?と思いましたが、VectorにはDerefトレイトが実装されているので、Derefトレイトの機能によってスライスに変換します。
「中身を取得する」という意味での参照外しです。
型は&[T]
となります。
let v_slice: &[i32] = &*v;
&*v
と&
をつけて参照型にしないと、「the size for values of type [{integer}]
cannot be known at compilation time」とサイズ不明エラーになります。サイズが決まっているポインターにする必要があります。
[..]スライシング
let v_slice: &[i32] = &v[..];
Vectorのスライスを分配したかった
これが本題でした。
スライスした値を分配したかったのです。
しかし、こちらはエラーになりました。
let [v1, v2, v3] = v.as_slice();
代入もパターンマッチングを使います。代入の場合は「論駁不可能」なパターンでないとダメなのです。
今回のようなVecotrは動的配列なので「論駁可能」なパターンとなります。
v1
、v2
、v3
に分配していますが、「本当にスライスの結果が3つしかないんでよね?」がコンパイル時点では不明です。もしかすると4つかもしれないよね?
let v = vec![1, 2, 3];
と定義しているから3つに決まっているじゃないか!とプログラマーは知っていますが、残念ながらコンパイラーはそこまで認識しません。。。
では、「論駁可能」でも分配する方法は、if let
もしくはmatch
を使います。
// スライスの要素を個別に変数に割り当てる
if let [a, b, c] = v.as_slice() {
println!("a = {}, b = {}, c = {}", a, b, c);
} else {
println!("スライスの長さが一致しません");
}
万が一、数が分配とスライスの結果で違った場合は、else
の処理を実行させます。else
の処理の実装は必須ではありませんが。
以上です。