遠くない未来にリリースされる TinyGo 0.28 は reflect package の互換性がかなり改善しています。
さらりと書きましたが、こんな感じでものすごい commit が登録されています。 軽く reflect で検索するだけで 113 commit という凄さ。 reflect で検索されない reflect 関連の commit もあるので、本当にハードワークだった感じです。
$ git log v0.27.0..dev --oneline | wc -l 319 $ git log v0.27.0..dev --oneline | grep reflect | wc -l 113
ということで、 reflect package の改善により encoding/json がかなり使えるようになったので試してみましょう。
簡単な JSON
TinyGo に含まれる targets/wioterminal.json を更に小さくした JSON で試してみました。
結果はこんな感じで、普通に正しく実行できます。
$ tinygo run . {"build-tags":["wioterminal"],"flash-method":"msd"}
ちょっと複雑な JSON
先程の例は簡単すぎるので、もう少し複雑な例を試してみます。 Twitter API の説明ページにあった JSON を Marshall / Unmashall してみます。
// https://developer.twitter.com/en/docs/twitter-api/v1/data-dictionary/overview const twitterJSON = ` { "created_at": "Thu Apr 06 15:24:15 +0000 2017", "id_str": "850006245121695744", "text": "1\/ Today we\u2019re sharing our vision for the future of the Twitter API platform!\nhttps:\/\/t.co\/XweGngmxlP", "user": { "id": 2244994945, "name": "Twitter Dev", "screen_name": "TwitterDev", "location": "Internet", "url": "https:\/\/dev.twitter.com\/", "description": "Your official source for Twitter Platform news, updates & events. Need technical help? Visit https:\/\/twittercommunity.com\/ #TapIntoTwitter" }, "place": { }, "entities": { "hashtags": [ ], "urls": [ { "url": "https:\/\/t.co\/XweGngmxlP", "unwound": { "url": "https:\/\/cards.twitter.com\/cards\/18ce53wgo4h\/3xo1c", "title": "Building the Future of the Twitter API Platform" } } ], "user_mentions": [ ] } } `
struct は以下の通り。
// https://mholt.github.io/json-to-go/ type AutoGenerated struct { CreatedAt string `json:"created_at"` IDStr string `json:"id_str"` Text string `json:"text"` User User `json:"user"` Place Place `json:"place"` Entities Entities `json:"entities"` } type User struct { ID int64 `json:"id"` Name string `json:"name"` ScreenName string `json:"screen_name"` Location string `json:"location"` URL string `json:"url"` Description string `json:"description"` } type Place struct { } type Unwound struct { URL string `json:"url"` Title string `json:"title"` } type Urls struct { URL string `json:"url"` Unwound Unwound `json:"unwound"` } type Entities struct { Hashtags []any `json:"hashtags"` Urls []Urls `json:"urls"` UserMentions []any `json:"user_mentions"` }
結果は以下の通り。 正しく処理され Go で実行したものと同じ結果になります。
$ tinygo run . {"created_at":"Thu Apr 06 15:24:15 +0000 2017","id_str":"850006245121695744","text":"1/ Today we’re sharing our vision for the future of the Twitter API platform!\nhttps://t.co/XweGngmxlP","user":{"id":2244994945,"name":"Twitter Dev","screen_name":"TwitterDev","location":"Internet","url":"https://dev.twitter.com/","description":"Your official source for Twitter Platform news, updates \u0026 events. Need technical help? Visit https://twittercommunity.com/ #TapIntoTwitter"},"place":{},"entities":{"hashtags":[],"urls":[{"url":"https://t.co/XweGngmxlP","unwound":{"url":"https://cards.twitter.com/cards/18ce53wgo4h/3xo1c","title":"Building the Future of the Twitter API Platform"}}],"user_mentions":[]}}
ソースコード全体は以下にあります。
まとめ
ということで、 TinyGo 0.28 の encoding/json は良い感じに動くと思います。 encoding/json が辛くて TinyGo を諦めていた人もいるかと思いますが、 TinyGo 0.28 がリリースされたらぜひ試してみてください。
なお、 encoding/json は激しく再帰呼出しとなって stack をかなり消費します。
マイコンで実装するときは、 --stack-size 10KB
のような形で stack を増やすなどが必要になるかもしれません。
おまけ
dev branch 版をダウンロードして試すこともできます。 以下の記事を参考にしてください。