0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rust Tips Vectorとスライス

Last updated at Posted at 2024-11-15

スライス型

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;    

:warning: &*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();

image.png
代入もパターンマッチングを使います。代入の場合は「論駁不可能」なパターンでないとダメなのです。
今回のようなVecotrは動的配列なので「論駁可能」なパターンとなります。
v1v2v3に分配していますが、「本当にスライスの結果が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の処理の実装は必須ではありませんが。

以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?