GoにいればGoに従え(33) byte型とbytes.Buffer型、TinyGo

Joseph Halfmoon

前回はcomplex128型などを使ってしまいました。マイコンでも使えるということで心強いけど滅多に使わんのではないかと。一方、普段から一番お世話になりそうなのが byte型であります。そして「byte」に似たものに「bytes」という標準パッケージがあり、そこにはbytes.Buffer型が存在。どんなもんだか。

※「GoにいればGoに従え」Go関連記事の総Index

※実機動作確認は Arm Cortex-M4FコアのNordic nRF52833チップ搭載、みんな大好き BBC micro:bit v2 機にTinyGoのオブジェクトを書き込んで行っています。

go言語の「変数型」の表示

本題に行く前にgo言語の変数の型を得たり表示するにはどしたらよいの?というところを実験しておきたいです。c言語における typeof演算子的なやつね。

    • fmtパッケージの「フォーマット指定子」

表示するだけなら、いつもお世話になっている fmt パッケージの中に %Tという「フォーマット指定子」が存在します。標準パッケージのマニュアルから1行引用するとこんな感じ。

%T a Go-syntax representation of the type of the value

    • reflectパッケージのTypeOf()関数

cのtypeof演算子的な関数はgoの標準パッケージの reflectの中に用意されとりました。その名もTypeOf()です。

上記2つの方法で、byte型の配列を観察してみるコードが以下に。

package main

import (
    "fmt"
    "reflect"
)

func main() {
    buf1 := []byte("abc")
    fmt.Printf("%T : %s\n", buf1, buf1)
    fmt.Printf("%s : %s\n", reflect.TypeOf(buf1).String(), buf1)
}
    • Go言語での実行結果

[]byte で作成した buf1は、どちらの方法でも[]uint8 だと識別されております。

Go_TypeOf

 

    • TinyGo言語での実行結果

まったく同じコードをTinyGo(ターゲット機はmicro:bit v2)で実行した場合の結果が以下に。”T”と素っ気ない識別?ダメじゃん。TinyGo_TypeOfa

どうも、この部分は、Go言語とTinyGo言語で挙動が違うみたいっす。

byte型と bytes.Buffer型

さて本題のbyte型です。以下の Go言語の文書をみてみます。

The Go Programming Language Specification

以下は引用です。

byte alias for uint8

byteの実体はuint8なので、先ほど既に出てきましたが、[]byteは、[]uint8なのでした。Arrayなのでbyte要素の書き換えができますが、最初に決定した大きさで変更はできない筈。まあ何かあったらスライスを使えと。

一方、bytesパッケージのbytes.Buffer型は同じく byte(=uint8)を詰め込むことができるのですが、「構造体」型で単純なarrayではないです。この型特有の「メソッド」多数を引き連れています。マニュアル文書は以下に。

bytes

今回実験のTinyGoソースコード

byte型のArrayは各要素に直接アクセスできて、かつlen()関数で長さが求まること。bytes.Buffer型は、長さを変更することができて、その長さはLen()メソッドで求められること。文字列に変換するにはString()メソッドがあることなどを実地にためしてみるコードです。

package main

import (
    "bytes"
    "fmt"
)

func main() {
    buf1 := []byte("abc")
    buf1[0] = '\x50'
    fmt.Printf("LEN(%d) : %s\n", len(buf1), buf1)
    var buf2 bytes.Buffer
    buf2.WriteString("ABC")
    buf2.Write([]byte("DEF"))
    fmt.Printf("LEN(%d) : %s\n", buf2.Len(), buf2.String())
}
実験結果

以下のコマンドラインにて、上記のソースをビルドしてUSB接続したターゲット機BBC micro:bit v2 に書き込みました(該当のプロジェクトフォルダ内で。)

$ tinygo flash --target microbit-v2

シリアルモニタをmicro:bit v2のUSBシリアルに向ければ以下の結果が得られます。TinyGo_byte_bytes

予定どおりの結果でありますな。

念のため、ホスト上のGo言語でも同じことをやってみました。Go_byte_bytes

結果は同じ。GoとTinyGoで挙動が一致していて嬉しいよ。

GoにいればGoに従え(32) math/cmplxをTinyGoで使う、ムムム早合点? へ戻る

GoにいればGoに従え(34) DevicesでHCSR04センサを動かす、TinyGo へ進む