Go
型アサーション
value, ok := <変数>.(<インタフェース>)
毎回忘れる。io.Writer のようなインタフェースで扱ってる型を具象化したりするときにしばしば出る
flush したいけど io.Writer には無い場合などにダウンキャストする必要がある、など
code:typeassertions.go
var output io.Writer
output = bufio.NewWriter(os.Stdout)
...
o, ok := output.(*bufio.Writer)
if ok {
o.Flush()
}
無名 interface も使える、go1.13 の errors.Unwrap でも使われている
code:assertion-method.go
u, ok := err.(interface {
Unwrap() error
})
別の type への変換
スライスにメソッドを追加したい時など
code:type.go
type Nums []int
func (n Nums) Sum() int {
...
}
// var で宣言
var nums Nums = []int{1,2,3}
// type キャスト
Nums([]int{1,2,3})
正規表現使うときは ` で囲むと楽
re := regexp.MustCompile(\`\w+\`)
複数行文字列も ` でかこむ
code:json.go
jsonString := `{
"message": {
"attributes": {
"key": "value"
},
"data": "hoge",
"messageId": "12345"
},
"subscription": "projects/project/subscriptions/test-subscription"
}`
TODO 頭の空白除去するいいやりかた
json.Unmarshal & Decode は private な値へデコードされない
ハマる
Array to Slice
[20]bytes(Array) を []bytes(Slice) にするイディオム
slice := array[:]
array[:] は array[0:len(array)] の省略
nil と空スライス
code:empty_slice.go
var s1 []string // nil
s2 := []string{} // slice
どちらも append など自然にできるし、返り値が slice の型でも nil を返せばよい
nil との比較だけ注意が必要、空かどうか調べるのに nil と比較するのではなく len などでしらべる
build -ldfrags
go build -ldflags "-X main.version=1.0" ldflags.go などすると version に "1.0" がセットされてコンパイルされる
const だとダメそう?
code:ldflags.go
package main
import "fmt"
var version = ""
func main() {
fmt.Println(version)
}
自作エラー
pkg/errors(相当) は 1.13 から組み込みになる
go build -tags=debug
// +build debug から始まるファイルをコンパイル時に含める // +build !debug は含めない
ビルド時に挙動を変えるのに使える
code:debug.go
// +build debug
var debug = true
code:production.go
// +build !debug
var debug = false
defer が取るのは関数呼び出し
変数の設定に使うなら closure 使って呼び出す
func の引数は defer 宣言時に評価した値が渡されるので注意
code:defer.go
package main
import "fmt"
func main() {
a := 1
defer func() {
fmt.Printf("a: %d\n", a) //=> 2
}()
a += 1
b := 1
defer func(value int) {
fmt.Printf("b: %d\n", value) //=> 1
}(b)
b += 10
}
byte array を含む構造体との json.Marshal & Unmarshal
base64 encode & decode される
Array and slice values encode as JSON arrays, except that []byte
encodes as a base64-encoded string, and a nil slice encodes as the
null JSON object.
型エイリアスと
type T U と type T = U は別
type T U は type T struct { ... /* U */ }
type T = U はエイリアス
U は T のメソッドを呼べる
redigo の返り値
キーに対する値が空であることは err == redis.ErrNil で判定できる
scopelint
使われているパッケージ一覧
Functional Option Pattern
import "net/url"
url を変数名に使いたいこと多すぎ問題
code:import.go
import (
urlpkg "net/url"
)