Cairoのコアライブラリには、Array型が実装されています。
他のプログラミング言語にある一般的な配列型と似ていますが、いくつか重要な違いがあります。
Array型の末尾だけで、効率よく削除できるのは先頭だけです。配列は、ArrayTrait::new関数やarray!マクロを使って作成できます。
let empty: Array<u32> = ArrayTrait::new();
let one_to_four = array![1, 2, 3, 4];
要素はArrayTrait::append関数を使って配列に追加できます。
let mut num_array = array![1, 2, 3, 4];
num_array.append(5);
// -> [1, 2, 3, 4, 5]
要素はArrayTrait::pop_front関数を使って配列から削除できます。
let mut one_to_four = array![1, 2, 3, 4];
one_to_four.pop_front();
// -> [2, 3, 4]
Cairoには、Arrayの「スナップショット」のように機能するSpan型もあります。
すべてのArrayは、ToSpanTrait::span関数を使うとSpanに変換できます。
let one_to_four = array![1, 2, 3, 4];
let one_to_four_span = one_to_four.span();
// -> [1, 2, 3, 4]
配列をSpanに変換するのはとても効率的です。Spanは、Cairoが配列の一部分を「見る」ことを可能にするデータ構造にすぎず、配列を一切変更しないからです。
配列をSpanに変換することで、CairoではArrayに直接許されるよりも多くの操作を行えます。たとえば、Spanの先頭から要素を削除できます。
let one_to_four = array![1, 2, 3, 4];
let mut one_to_four_span = one_to_four.span();
one_to_four_span.pop_back();
// -> [2, 3, 4]
pop_backを呼び出すには、mutキーワードを使ってone_to_four_spanを可変にする必要があったことに注意してください。pop_backは、Spanが「見ている」配列の範囲を短くすることで、Spanを変更します。
マジシャンになるElyseは、基本をいくつか練習する必要があります。
Elyseは、思いどおりに動かしたいカードの山を持っています。
少し簡単にするために、使うカードは1から10までに限っています。
カードの山はArrayで表され、山の一番下が配列の先頭、山の一番上が配列の末尾になります。
関数insert_topを実装してください。この関数は、渡された新しいカードを山の一番上に追加した、山のコピーを返します。
let stack = array![5, 9, 7, 1];
insert_top(stack, 8);
// -> [5, 9, 7, 1, 8]
関数remove_top_cardを実装してください。この関数は、一番上のカードを取り除いた山のコピーを返します。
渡された山が空の場合は、元の山をそのまま返します。
let stack = array![3, 2, 6, 4, 8];
remove_top_card(stack);
// -> [3, 2, 6, 4]
関数insert_bottomを実装してください。この関数は、渡された新しいカードを山の一番下に追加した、山のコピーを返します。
let stack = array![5, 9, 7, 1];
insert_bottom(stack, 8);
// -> [8, 5, 9, 7, 1]
関数remove_bottom_cardを実装してください。この関数は、一番下のカードを取り除いた山のコピーを返します。
渡された山が空の場合は、元の山をそのまま返します。
let stack = array![8, 5, 9, 7, 1];
remove_bottom_card(stack);
// -> [5, 9, 7, 1]
関数check_size_of_stackを実装してください。この関数は、山のサイズが、渡されたstack_sizeと同じかどうかを調べます。
let stack = array![3, 2, 6, 4, 8];
check_size_of_stack(stack, 4);
// -> false
Cairoで配列を扱うのが他のプログラミング言語ほど単純ではない理由を理解するには、Cairoが不変のメモリモデルを採用していることを覚えておくとよいでしょう。つまり、一度メモリセルに書き込まれると、それを上書きすることはできず、読み出すことしかできません。
この言語ではこの性質がある程度抽象化されているため、エンジニアは変数を宣言し、あたかも可変であるかのように使えます。
そのため、コードを書くのは少し大変になります。特にArray型を使うコード(ByteArrayも含みます。これは内部的には「バイトの配列」です)ではそうですが、その代わり、信頼できないマシン上でも安心して実行できる_証明可能_なプログラムを書けるようになります。このトレードオフには、それだけの価値があります。