前回はTinyGoでも「フルの」Goの標準ライブラリが立派に使える、ということで「値によって順番をつけて」データを格納してくれるheapを使ってみました。さて今回はその流れで container/list を使ってみます。順番を管理できるデータ構造です。それにどんな型のデータを入れても良いし。よくあるリスト構造だね。
※「GoにいればGoに従え」Go関連記事の総Index
配列、スライス、マップ
今回はlist構造の練習なのに、先に不必要にlistのような可変長のコンテナを使うなよ、と書いておかないではいられません。限られたRAMしかないマイコンを想定しているTinyGoなので、可変長の構造を使うとメモリがいつ溢れるかと気が気じゃないからです。配列、こいつは固定長デス。配列で済むのなら配列にしとけ、と。
さてよく使う、配列、スライス、マップはだいたい以下のような感じです。知らんけど。
-
- 配列。固定長、単一要素型。
- スライス。可変長。単一要素型。ただしデータの実体は配列などの中に存在。
- マップ。キーとバリューの連想配列。可変長。キーとバリューはそれぞれ単一要素型。
スライスが可変長のクセにあまり罪悪感なく使えるのは、データの実体は配列などの中にあり、カリソメにそれらを「借りてる」存在だからです。ホントか?
container/list
さて一方、標準ライブラリの container/list パッケージはカリソメでないガチな可変長のデータ構造らしいっす。
-
- ガチに要素の順序をつけられる(順番はプログラマがフルに制御可)
- ガチに要素型Any。矢でも鉄砲でも(いや整数でも浮動小数でも文字でも)もってこい。
です。まあPythonなど使っていたらフツーのリスト構造ってこってす。TinyGoは「小さく」てもコンパイラなので立派っす。
御本家Go様(TinyGo様ではありませぬ)のドキュメントページが以下に。
また、TinyGo様の以下のページのチェック表をみると
テストのところにもチェック印ありの安心パッケージです。
今回実験のTinyGoソースコード
今回のソースも御本家Go様の例題ソースをチョイ変です。殊更に Any な型のデータが突っ込めるぜ、という点を「強調」してみました。
package main import ( "container/list" "fmt" ) func main() { lis := list.New() elemZ := lis.PushBack("Z") elem1 := lis.PushFront(1) lis.InsertBefore(99, elemZ) lis.InsertAfter(2, elem1) for elem := lis.Front(); elem != nil; elem = elem.Next() { fmt.Println(elem.Value) } }
実験結果
上記のソースをビルドしてターゲット機BBC micro:bit v2 に書き込むのはプロジェクトフォルダ内でいつものように以下のコマンドラインです。
$ tinygo flash --target microbit-v2
予定どおりの順番で、数字と文字が混ざっておりますな。よかった。