この記事では、Go言語でコードを書いていて、(主に勘違いにより)ハマってしまったことについて紹介します。
json.Unmarshalが成功してるのにデータが入ってない!←それPublicにしないとだめだよ
下記のコードはjson パッケージからExampleを抜粋、改悪したものです。
コード例(NGパターン)
package main
import (
"encoding/json"
"fmt"
)
func main() {
var jsonBlob = []byte(`[
{"Name": "Platypus", "Order": "Monotremata"},
{"Name": "Quoll", "Order": "Dasyuromorphia"}
]`)
type Animal struct {
name string `json:"Name"` // NG. name -> Name
order string `json:"Order:` // NG. order -> Order
}
var animals []Animal
err := json.Unmarshal(jsonBlob, &animals)
if err != nil {
fmt.Println("error:", err)
}
fmt.Printf("%+v", animals)
}
これ、当然データがanimalsに入りません。jsonパッケージから、Animal.nameとAnimal.orderが参照できないからです。
req = http.NewRequest(http.MethodGet, anyUrl, queryParameter)でクエリ付きGetリクエスト←クエリはreq.URL.RawQueryに登録しないとだめだよ
コード例(コメントにNGパターン)
// クエリパラメータの作成
v := url.Values{}
v.Add("q", query)
// NG クエリパラメータをrequest bodyにセット。
// req, _ := http.NewRequest(http.MethodGet, urlStr, strings.NewReader(v.Encode()))
// "普通の"Getリクエストはrequest bodyなし
req, _ := http.NewRequest(http.MethodGet, urlStr, nil)
// クエリパラメータは直接RawQueryにセット
req.URL.RawQuery = v.Encode()
$ any-go-tool -s='\t'でタブ文字を渡す←ツール側で'\t'を処理する必要ありますよ || -s=$'\t'
コマンドラインツールを作っていて、引数に'\t'(タブ文字)や'\n'(改行)などエスケープ記法の値を渡して利用する場合、ツール側にそれらの文字を扱う実装が必要になります。またはBashのANSI C like strings機能などを使って、タブ文字の文字コードを渡せば、実装なしにタブ文字などを扱えます。
コマンド実行例
# $'string'のフォーマットで、Bashはエスケープ記法の文字列を処理してからアプリに渡す
$ any-go-tool -s=$'\t'