rs.nkmk.me

Rustで空のVec・配列を生成(Vec::newなど)

Posted: | Tags: Rust, ベクタ

Rustで空のベクタVecや配列を生成するには、Vec::newVec::with_capacityなどを使う。

任意のサイズ・値で配列やベクタを生成する方法については以下の記事を参照。

空のベクタVecを生成: Vec::new, Vec::with_capacity, vec!

Vec::new

ベクタの関連関数Vec::newで空のベクタを生成できる。

生成後に要素を追加すると、その型からベクタの型が推論される。

let mut v = Vec::new();
v.push(100); // Vec<i32>

let mut v = Vec::new();
v.push(String::from("abc")); // Vec<String>
source: vec_empty.rs

ターボフィッシュ::<>や型注釈で明示的に型を指定することも可能。

let v = Vec::<u8>::new();
let v: Vec<u8> = Vec::new();
source: vec_empty.rs

ターボフィッシュや型注釈が無く、要素が追加されず型推論もできない場合はコンパイルエラーとなる。

// let v = Vec::new();
// error[E0282]: type annotations needed for `std::vec::Vec<T>`
source: vec_empty.rs

なお、追加する値がすでに決定している場合はvec!でベクタを生成するほうが効率的。Clippyでは、Vec::newで空のベクタを生成した直後にpushで要素を追加すると警告される。

Vec::with_capacity

Vec::newで生成したベクタの容量capacity0

Vec::with_capacityを使うと、指定したサイズの容量を確保して空のベクタを生成できる。

let v: Vec<u8> = Vec::new();
assert_eq!(v.capacity(), 0);

let v: Vec<u8> = Vec::with_capacity(100);
assert_eq!(v.capacity(), 100);
source: vec_empty.rs

Vec::newと同様、ターボフィッシュで型を指定することも可能。ターボフィッシュや型注釈を省略するとpushで追加した要素の型からベクタの型が推論される。推論できない場合はエラー。

let v = Vec::<u8>::with_capacity(100);

let mut v = Vec::with_capacity(100);
v.push(100); // Vec<i32>

let mut v = Vec::with_capacity(100);
v.push(String::from("abc")); // Vec<String>

// let v = Vec::with_capacity(100);
// error[E0282]: type annotations needed for `std::vec::Vec<T>`
source: vec_empty.rs

最終的に必要な要素数があらかじめ分かっている場合はVec::with_capacityを使うとpushによる再割り当てを避けることができるので効率的。

ベクタにおける容量capacityについての詳細は以下の記事を参照。

vec!

vec!マクロで空のベクタを生成することもできる。

Vec::newと同様。

let mut v = vec![];
v.push(100); // Vec<i32>

let mut v = vec![];
v.push(String::from("abc")); // Vec<String>

let v: Vec<u8> = vec![];

// let v = vec![];
// error[E0282]: type annotations needed for `std::vec::Vec<T>`
source: vec_empty.rs

すべての要素を同じ値xで生成するvec![x; N]の書き方の場合、要素数N0とすると空のベクタが生成される。

xそのものが要素として追加されるわけではないので、値が異なっていても型が同じであればその型の空のベクタが生成される。

let v = vec![true; 0]; // Vec<bool>
let v = vec![false; 0]; // Vec<bool>
source: vec_empty.rs

xに式を指定した場合は、一度評価され即座にドロップされるので注意。

Also, note that vec![expr; 0] is allowed, and produces an empty vector. This will still evaluate expr, however, and immediately drop the resulting value, so be mindful of side effects. vec! in std - Rust

let v = vec![String::from("abc"); 0]; // Vec<String>
source: vec_empty.rs

空の配列を生成: []

空の配列は以下のように[]で生成する。上述のvec!と同様に、型注釈で型を指定するか[x; N]N0とする。

let a: [i32; 0] = [];
let a: [u8; 0] = [];

// let a = [];
// error[E0282]: type annotations needed for `[_; 0]`

let a = [100; 0]; // [i32; 0]
let a = [100_u8; 0]; // [u8; 0]

関連カテゴリー

関連記事