nakamura244 blog

所属団体とは関係なく、個人的なblog

golang1.9系から1.11.2にあげてみての感想

はじめに

業務で1.9系で使っていて1.11.2にあげた。

まぁリリースノートを見ればどの辺りがどう変わったかは大体わかるが、ある程度稼働しているコードのリポジトリでバージョンをあげる事で何となく得られる知見や理解が深まった部分があったので残しておく

Go 1.9 Release Notes - The Go Programming Language

Go 1.10 Release Notes - The Go Programming Language

Go 1.11 Release Notes - The Go Programming Language

test関連

vet

今まではcircleciのjobにvetやlintだけを流す静的チェック系のテストを定義していたが、test実行のまえにvetが-vet=off.にしない限り自動で動く。

なのでcircleciのjobを減して良いなと感じた

https://golang.org/doc/go1.10#test

test結果のキャッシュ

修正を加えていない部分に関しては毎回テストが走る事がなく、キャッシュからresultを返してくれる。

testは早ければ早いほど自分は嬉しいのですごくありがたい。

もちろん、キャッシュをさせずに一通り実施したい場合はオプションが存在する -count=1

ちなみにどこにキャッシュを作ってるのだろうかと気になって調べて見たら書きに書いてあった

https://github.com/golang/go/blob/master/src/os/file.go#L346-L382

macであれば$HOME/Library/Caches配下ですね

へーっと思ったら、その辺りを解説されているエンジニアさんがいらっしゃいました

How Go cache tests - Speaker Deck

先にこのスライドを目にしていれば...

bug fix系かな

1.

loggingにlogrusを使っているが、今ままで下記のようなコードがあった

GitHub - sirupsen/logrus: Structured, pluggable logging for Go.

if err != nil {
  Logger.Errorf("failed to xxx err:%#v, p_id:%d, u_id:%d", err, iv.PxxxID, iv.UxxxID)
}

iv.PxxxIDintだったが、iv.UxxxIDsql.NullInt64 でした。がエラーにはなっていませんでしたが、1.11.2にあげてからは怒られるようになりました。

正しく、iv.UxxxID.Int64としてあげなきゃいけないなと気づけてありがたい。

なので下記のように修正

if err != nil {
  Logger.Errorf("failed to xxx err:%#v, p_id:%d, u_id:%d", err, iv.PxxxID, iv.UxxxID.Int64)
}

2.

これまだ要調査という感じですが、下記のようなコードがあったとします。

main.go

func sample() string {
    var i float64
    i = 444
    fmt.Printf("%d",i)
    return "aaa"
}

func main() {
    fmt.Println(sample())
}

main_test.go

func TestMain_sampe(t *testing.T) {
    actual := sample()
    expected := "aaa"
    if actual != expected {
        t.Errorf("got: %v\nwant: %v", actual, expected)
    }
}

1.9.7の場合

  • go run main.goすると私の期待値通り%!d(float64=444)aaaと返ってくる
  • go test -run TestMain_sampeすると問題なくPASSする

1.11.2の場合

  • go run main.goすると私の期待値通り%!d(float64=444)aaaと返ってくる
  • go test -run TestMain_sampeすると./main.go:13: Printf format %d has arg i of wrong type float64という感じで怒られる

ちなみにbuildはどちらでも何もエラーを出力する事なくできました。

go rungo testをもうちょっと詳しくならないと理由がわからないですね。次の持ち越し課題にしておく。

goimports

indentがちゃんと揃うようになった

before

   i := &models.Ixxxx{
        PxxxxxxID:                i.PxxxxxxID,   
        TotalxxxxxxxxxPrice:      sql.NullInt64{Int64: i.TotalxxxxxxxPrice, Valid: true},  
        UxxxID:       sql.NullInt64{Int64: i.UxxxID, Valid: true}, 
        Type:         sql.NullInt64{Int64: i.Type, Valid: true},   
    }    

after

   i := &models.Ixxxx{
        PxxxxxxID:                i.PxxxxxxID,   
        TotalxxxxxxxxxPrice:      sql.NullInt64{Int64: i.TotalxxxxxxxPrice, Valid: true},  
        UxxxID:                   sql.NullInt64{Int64: i.UxxxID, Valid: true},
        Type:                     sql.NullInt64{Int64: i.Type, Valid: true},   
    }    

vetをかけた際に出ていたcannot load packageが解決された

以前はgo vet -v ./...をした時によく(can't find import: ~と出てたが、そのloadが解決されてちゃんと動くようになった

最後にちょっと気になっているところ

1.11でWebAssemblyvgoといったところが出ていた。まだ全然試せていないが、vendorも時期に消し去る時がくるようだなーと。