20210802のGoに関する記事は4件です。

Goのインストールとチュートリアルメモ

Go使ったことない人間がGoのインストールしてから公式のチュートリアル進めて行くにあたって躓いた点などをメモ。 なおMac前提。(随時追記) インストール 公式から最新版をダウンロードしてインストールする よくわからんけどgoコマンドが command not found になってしまうっ……!ってなったので、~/.bash_profileをいじいじしてパスを通す。 ~/.bash_profile # goのインストール先は/usr/local/goになる export PATH="/usr/local/go/bin:$PATH" そんでもってターミナル再起動かsourceで再読み込み $ source ~/.bash_profile これでようやくgoコマンドが動いた $ go version go version go1.16.6 darwin/amd64 $GOPATH もなかったので指定しとく ~/.bash_profile # GOPATHは適当に指定してもOK export GOPATH=$HOME/.go sourceで読み込んで準備完了。 $ source ~/.bash_profile $ echo $GOPATH /Users/xxxxx/.go チュートリアル1: Get started with Go 前半について。 package main の意味とか、 go run 時の動作とかはこのサイトがすごくわかりやすかった。 go mod init (path)については、作成したmoduleをpublishする際には注意が必要ってことっぽい。 The name is the module's module path. In most cases, this will be the repository location where your source code will be kept, such as github.com/mymodule. If you plan to publish your module for others to use, the module path must be a location from which Go tools can download your module. 後半について。 go mod tidy で rsc.io/quote のモジュール本体がどこに行ったのかというと、 $GOPATH 配下にダウンロードされてた。なるほどね。 $GOPATH ── pkg ─┬─ mod ─┬─ cache │ ├─ golang.org │ └─ rsc.io ── quote@v1.5.2 └─ sumdb go run . で結構時間かかるのはコンパイルしてるから。上に貼ったサイト参照。 ※以降のチュートリアルは環境整っちゃえば大丈夫そう
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Golang】TinyGo で WebAssembly.instantiate(): Import #0 module="wasi_snapshot_preview1" error: module is not an object or function

Docker の TinyGo で疲労コンパイる TinyGo の Docker イメージ tinygo/tinygo:latest で wasm(WebAssembly のバイナリ)をビルドして実行したら、"wasi_snapshot_preview1" エラーがブラウザのデベロッパーツールのコンソールに表示される。 consoleログ WebAssembly.instantiate(): Import #0 module="wasi_snapshot_preview1" error: module is not an object or function wasi_snapshot_preview1 モジュールがないのはわかるのですが、よくわりません。でも Go で wasm をコンパイルすると動くんです。 「WebAssembly.instantiate(): Import #0 module= "wasi_snapshot_preview1" error: module is not an object or function」でググっても node.js の内容ばかり。Golang のスポンサー情報が欲しいのです TinyGo 公式の "wasi_snapshot_preview1" がらみの Issues を見ても、むしろ wasi_unstable だったのを wasi_snapshot_preview1 にしたくらいの情報しかありません。どうしよう。 TL; DR (今北産業) 原因 *.wasm バイナリと Javascript の関数を紐づける wasm_exec.js で違うものが使われています。 wasm_exec.js は、使用しているコンパイラが提供している wasm_exec.js を使うこと。 Go のマスターブランチから持って来てはいけない。 wasm_exec.jsの保存先: コンパイラが Go の場合: $(go env GOROOT)/misc/wasm/wasm_exec.js コンパイラが TinyGo の場合: /usr/local/tinygo/targets/wasm_exec.js TS; DR (正妻公式ドキュメント嫁に叱られる) 利用中のコンパイラで提供している wasm_exec.js を使うこと can't run wasm module in browser: LinkError: WebAssembly Instantiation | Issue #29827 | Go | Golang @ GitHub TinyGo の Docker を使う場合は wasm_exec.js も実行環境にコピーするのを忘れないように Building | Using WebAssembly | Guides | Docs @ TinyGo.org 所感 「Go で wasm 動いた!」と Hello, world! したくらいで喜んでいたのも束の間。せっかちなものだから次の基本を踏まずに「いままで作ったアプリを wasm る!」と思うも test が思うように動かない。わざと失敗させてるエラーもパスしてしまうのです。 「Golang で wasm るベストプラクティス」なる記事を読んでいたら「wasm を gzip するのがブラウザ(ネットワーク)に優しいけど、TinyGo 使ったらもっと小さくなるでよ」的なことが書いてありました。 "Best Practices for WebAssembly using GoLang (1.15+)" | GitConnected @ Medium 確かに、なんかそれっぽいことはネットサーフィンしていて見かけた気がします。しかし、公式ドキュメントをしっかり読まないで思いつきで動いちゃうものだから、動くものも動かない。ちゃんと書いてありました。 どうせまた忘れるので、未来の自分のググラビリティとして備忘録Qiitaに残します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Goの静的解析ツールを作成した

はじめまして、しぶちゃりです。 今回はGoの静的解析ツール nilassign の紹介をさせていただきます。 nilに代入することで発生するpanic Cをはじめとしたポインタの概念が存在する言語ではnullにデータを渡すことで言語ごとにエラーが発生します。これはデータを代入するアドレスが存在しない(null)にも関わらず利用するためです。 その例に漏れず、Goのnull型に相当するnilも、データを渡したり、参照することでエラーが発生します。以下がその例です。 package main import ( "fmt" ) func main() { var i *int *i = 1 fmt.Println(i) } The Go Playground panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x49777f] goroutine 1 [running]: main.main() /tmp/sandbox000987391/prog.go:9 +0x1f またポインタ型のフィールドを持つ構造体でもruntime panicが起きます。 package main import ( "fmt" ) func main() { n := Node{} n.Value = 1 // OK n.ChildNode.Value = 1 // runtime panic fmt.Println(n) } type Node struct { Value int ChildNode *Node } The Go Playground panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x497783] goroutine 1 [running]: main.main() /tmp/sandbox811268421/prog.go:10 +0x23 このようにruntime panicでプログラムが異常終了するにも関わらず、代入自体は言語仕様的に代入可能性を満たすため、できてしまいます。 また、go vetコマンドを用いてもこのエラーは検出されないためgo buildコマンドでコンパイル自体は成功します。そのため、複雑なデータ構造の操作などが発生した際に思わぬバグを埋め込んでしまう可能性があります。 nilassignでnil参照を検出する 上記のようなエラーを事前に検出し防ぐために、nilassignというlinterを作成しました。 このlinterを用いることで、コンパイルよりも前にruntime panicを防ぐことが可能です。 以下がその例です。 package main func main() { { var i *int *i = 2 // ng } { n := &Node{} n.Val = 1 // ok *n.Pval = 1 // NG n.Node.Val = 1 // NG n.Node.Node.Val = 1 // NG n.ChildNode = &Node{Val: 1} // OK n.PVal = &num // OK } } type Node struct { Val int Pval *int Node *Node } fish go vet -vettool=(which nilassign) ./... ./main.go:6:3: this assignment occurs invalid memory address or nil pointer dereference ./main.go:13:3: this assignment occurs invalid memory address or nil pointer dereference ./main.go:14:3: this assignment occurs invalid memory address or nil pointer dereference ./main.go:15:3: this assignment occurs invalid memory address or nil pointer dereference bash $ go vet -vettool=`which nilassign` ./... ./main.go:6:3: this assignment occurs invalid memory address or nil pointer dereference ./main.go:13:3: this assignment occurs invalid memory address or nil pointer dereference ./main.go:14:3: this assignment occurs invalid memory address or nil pointer dereference ./main.go:15:3: this assignment occurs invalid memory address or nil pointer dereference このツールはCIにも組み込むことが可能です。 CircleCI - run: name: Install nilassign command: go get github.com/sivchari/nilassign - run: name: Run nilassign command: go vet -vettool=`which nilassign` ./... GitHub Actions - name: Install nilassign run: go get github.com/sivchari/nilassign - name: Run nilassign run: go vet -vettool=`which nilassign` ./... golangci-lint経由でも利用可能 上記のlinterはgolangci-lintにも組み込まれているため、golangci-lint経由で利用することも可能です。 golangci-lintはよく利用しており、お世話になっているため、自分が作成したlinterがマージされたのはとても嬉しかったです。 まとめ 今回ご紹介したlinterはGitHubで公開しています。もしいいなと思ったらスターをいただけるとモチベーションにつながるのでとても嬉しいです。 最後までお読みいただきありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

excelizeをgo installするとエラー

excelizeをインストールする際に下記のエラー ラスト2行を訳すとgithub.com/xuri/excelize/v2のパスが必要だけど、github.com/360EntSecGroup-Skylar/excelize/v2が宣言されているよとのこと ついこの間まで使えていたので、なんか変更が入ったみたいですね $ go install github.com/360EntSecGroup-Skylar/excelize/v2 go: finding module for package github.com/360EntSecGroup-Skylar/excelize/v2 go: downloading github.com/360EntSecGroup-Skylar/excelize/v2 v2.4.1 go: found github.com/360EntSecGroup-Skylar/excelize/v2 in github.com/360EntSecGroup-Skylar/excelize/v2 v2.4.1 go: github.com/360EntSecGroup-Skylar/excelize/v2: github.com/360EntSecGroup-Skylar/excelize/v2@v2.4.1: parsing go.mod: module declares its path as: github.com/xuri/excelize/v2 but was required as: github.com/360EntSecGroup-Skylar/excelize/v2 公式のgithubを確認 Installationのところに If your packages are managed using Go Modules, please install with following command. go get github.com/xuri/excelize/v2 とあるので、まずmain.goのインポートのパスを変更 import ( "fmt" "github.com/xuri/excelize/v2" ) 次に実行コマンドに指定のパスを変更 $ go install github.com/xuri/excelize/v2 $ go install github.com/xuri/excelize/v2 go: finding module for package github.com/xuri/excelize/v2 go: found github.com/xuri/excelize/v2 in github.com/xuri/excelize/v2 v2.4.1 成功しました
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む