[Rust学習] 配列型とタプル型

2024年4月4日

Rust プログラミング 学習

eyecatch プログラミングの醍醐味は、配列データを上手に扱えることです。 複雑な配列データを組み合わせ変更したり、細かな検索ポイントで抽出できるようになると、もはやデータは怖くなくなるし、 SQLとのつなぎ込みなどもお手軽にできるようになります。 そんな配列データについての学習を進めていきます。

配列型 (Array)の説明

安全性とメモリ管理

Rustの配列は、メモリ安全性に重点を置いた設計がされています。 コンパイル時に範囲外アクセスや未初期化の可能性を検出し、実行時エラーを防ぐ仕組みがあります。

配列の定義

配列は同じ型の要素を固定長で持つデータ構造です。要素の型と長さを指定して宣言します。 宣言方法は [Type; Length] の形式で、次のように記述します。 let arr: [i32; 5] = [1, 2, 3, 4, 5]; 要素には文字列も使えます。 array.rs fn main(){ let arr = ["foo", "bar", "baz"]; println!("{}", arr[0]); } 実行 $ rustc array.rs $ ./array > foo

要素へのアクセス

配列の要素には、インデックスを使ってアクセスします。インデックスは0から始まります。 次のようにして配列の最初の要素にアクセスできます。 let first_element = arr[0]; これは、他のプログラム言語でも全く同じルールなので、さほど混乱しないですね。

配列の初期化

配列を初期化する際、要素を一つずつ指定して初期化する方法や、同じ値で初期化する方法があります。 指定された要素数だけ値を持つ配列を作成するには、[value; size] の形式を使います。 let zeros = [0; 3]; 上記は [0, 0, 0] を持つ配列を作成します。

配列の操作

配列には、要素の追加や削除ができません。 配列のサイズは固定されているからですね。 しかし、要素の値を変更することは可能です。arr[index] = new_value; のようにして要素を更新できます。 この点は、他のプログラム言語のように手軽にpush、unshift, pop , shiftができないので、これらに慣れてしまっている場合は、思考の転換が必要になりますね。

配列のスライス

配列から一部の要素を取り出すには、スライス(Slice)を使用します。 スライスは &[Type] の形式で表現され、元の配列の一部を参照することができます。

多次元配列

Rustでは、配列の配列を使って多次元配列を表現します。 let matrix: [[i32; 3]; 2] = [[1, 2, 3], [4, 5, 6]]; 上記のようにして2x3の行列を表現できます。

連想配列

Rustで連想配列を扱うのは、配列とは違うやり方に混乱してしまいます。 hash.rs fn main(){ use std::collections::HashMap; let mut hash = HashMap::new(); hash.insert("hoge".to_owned(), 100); hash.insert("fuga".to_owned(), 200); hash.insert("hage".to_owned(), 300); println!("{}", hash["fuga"]); } 実行 $ rustc hash.ts $ ./hash > 200 publicのuse区を使って、HashMapというモジュールを読み込まないといけないようですね。 useの使い方はまた後日行いたいと思います。

タプル

下記参考ページにあったものをコピペしてみました。 tuple.rs fn main() { // タプルを作成 let tuple = ("リンゴ", 5, 100); // タプルを出力 println!("{:?}", tuple); // 各要素へアクセス println!("--- 各要素へアクセス ---"); println!("商品:{}", tuple.0); println!("個数:{}", tuple.1); println!("値段:{}", tuple.2); // 分配 println!("--- 分配 ---"); let (商品, 個数, 値段) = tuple; println!("商品 = {}", 商品); println!("個数 = {}", 個数); println!("値段 = {}", 値段); } このコードが非常にわかりやすかったです。 配列と少し違う扱い方が理解できればいいのかな・・・と。 個人的な理解としては、for文などで使いたい場合は「配列」で、データをまとめて任意的に使いたい場合はタプルなのかな・・・と。 実行 $ rustc tuple.rs $ ./tuple > ("リンゴ", 5, 100) > --- 各要素へアクセス --- > 商品:リンゴ > 個数:5 > 値段:100 > --- 分配 --- > 商品 = リンゴ > 個数 = 5 > 値段 = 100

あとがき

C言語でも配列で苦労したことを思い出しました。 インタプリタ言語をやっていると、とにかくメモリ管理のことを何も考えずにプログラミングコードの見た目の綺麗さや、なんやかんやの効率性のみで進めてしまうんですが、 コンパイル系言語は、とにかくメモリとの戦いです。 Rustの配列を制するものは、メモリ管理とプログラムの効率性を制する事ができるのかもしれませんね。(半分ウソです) 実は、配列にはもっと期待したいことがあり、 JSONデータの分解やデータ型への変換、配列内部の検索や、抽出、書き換えなどを効率化出来る方法、 こうした事がスラスラとできるようになると、かなりのRust手練れになることができるでしょうね。 そして、タプルと配列をうまく使い分けて使いこなすのがRustマスターへの道なのではないかと心に刻みました。 そういえば、Rustプログラマーの事は何ていうんでしょう? やっぱり、ラスター(Ruster)なんですかね?

参考

Rustにおける連想配列リテラル・ハッシュリテラル相当 Rustのpub useの使い所 sub: 【Rust】タプル型、配列型 Rust By Example 日本語版 : タプル Rust ツアー: 複数の戻り値

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。