#はじめに
いつも使っている言語のArrayのような存在がrustには3種類あった…
- 配列
- スライス
- Vec
みんな微妙に挙動が違う
いつまでも雰囲気で扱っていないでテーマを絞って挙動の違いについて掘り下げてみる
#テーマ
- 所有権
- ライフタイム
- 使用できるmethod
#概要
配列 | スライス | Vec | |
---|---|---|---|
簡易説明 | 単一の型のオブジェクトの集合 | データへのポインタと長さ | データへのポインタと長さ、容量 |
構造体サイズ | 静的 | 動的(DST) | 静的 |
動的可変長 | × | × | ○ |
プリミティブ | ○ | ○ | × |
#所有権
Vecのみ非プリミティブ
プリミティブとCopy
- 全プリミティブの型はCopyを実装している
- Copyを実装していると所有権が移るのではなくオブジェクトのコピーが新しく生成される
配列はプリミティブ。Vecは非プリミティブ
fn main() {
let tempArrayA: [i16; 3] = [1, 2, 3];
let tempArrayB: [i16; 3] = tempArrayA;
assert_eq!(tempArrayA, tempArrayB);
/* 所有権が移動した変数を使用したためエラー */
// let tempVecA: Vec<i16> = Vec::new();
// let tempVecB: Vec<i16> = tempVecA;
// assert_eq!(tempHogeA, tempHogeB);
}
#ライフタイム
スライスのみ動的サイズの型(DST)
動的サイズの型(DST)とファットポインタ
- スライスはDynamically Sized Type(DST: 動的サイズの型)
- DSTはサイズやアライメントが静的には判断できない
- rustが型を静的解析するために他のポインタを利用してファットポインタを生成し、サイズやアライメントを示してやる必要がある
pub fn return_vec() -> Vec<i16> {
vec![1,2,3]
}
pub fn return_array() -> [i16; 3] {
[1, 2, 3]
}
// スライスだけではファットポインタを生成できないのでエラー
// pub fn return_slice() -> [i16] {
// &[1, 2, 3]
// }
// エラー
// pub fn return_slice() -> [i16] {
// &[1, 2, 3]
// }
// 引数を使ってファットポインタを生成してやる
pub fn return_slice<'a>(slice: &'a [i16]) -> &'a [i16] {
slice
}
// 引数を使ってファットポインタを生成してやる
pub fn return_slice_implessly(slice: &[i16]) -> &[i16] {
slice
}
#使用できるmethod
特定条件でスライスに型が強制変換される
型の強制変換
- rustはポインタやライフタイムのために型を強制的に変換する時がある
- mutable => immutableとかderefrenceとか
#配列を使っているつもりが実はsliceを使っている
let tempArrayA = [1, 2, 3];
// sliceに型を強制変換
for i in &tempArrayA {
println!("{:?}", i);
}
// sliceに型を強制変換
for i in tempArrayA.iter() {
println!("{:?}", i);
}
まとめ
- Vecのみ非プリミティブ
- スライスのみ動的サイズの型(DST)
- 特定条件でスライスに型が強制変換される
ご静聴ありがとうございました
参考リンク
- https://doc.rust-lang.org/std/primitive.array.html
- https://doc.rust-lang.org/std/slice/
- https://doc.rust-lang.org/std/vec/struct.Vec.html
- https://doc.rust-lang.org/beta/nomicon/exotic-sizes.html
- https://rust-lang-ja.github.io/the-rust-programming-language-ja/1.6/book/ownership.html
- https://doc.rust-lang.org/nomicon/coercions.html
- https://stackoverflow.com/questions/30794235/what-is-the-difference-between-slice-and-array