Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go活

67de06c6cee3ece0f56494e91e48117e?s=47 tkitsunai
December 13, 2019

 Go活

社内でgolangを採用したときにチームメンバーに展開した資料

67de06c6cee3ece0f56494e91e48117e?s=128

tkitsunai

December 13, 2019
Tweet

Transcript

  1. Go活 実用編 更新:2019/12/12

  2. Goの何が良いのか ・マスコットの存在  ・かわいい ・エコシステムの強さ  ・パッケージマネージャ、 Linter、Formatter、ビルドなど ・標準パッケージの強さ  ・シンプルが故に、net/httpパッケージ、encoding/jsonパッケージなどライブラリに頼らなくても一定水準の パッケージが提供される

  3. Goの何が良いのか 2 ・覚えることが少ない  ・go routine(channel), for, if, struct(methods), interface, slice,

    pointerぐらいしかまずは覚えない ・ノリ(雰囲気)で書ける ・Simple Go Way  ・言語機能でやれることは高が知れてる ・Duck Typing
  4. Goの常識 (基本) ・ゼロ値、0, false, “” ・structも同様(後述) var i int var

    f float64 var b bool var s string
  5. Goの常識 (宣言) ・型宣言(var)+初期化、型推論(:=) type,const,varはまとめてかける type ( User struct {} Human

    struct {} )
  6. Goの常識 (Struct Constructor) ・`new(Type) *Type`という組み込み関数が存在する(ゼロ値のポインタが帰ってくる) ・引数ありならFactoryをExport関数として定義する type Person struct {

    name string } func NewPerson(name string) *Person { return &Person{name: name} }
  7. Goの常識 (Panic/Recover) ・Panicを使うケースはほぼない  ・Recoverでキャッチすることは可能だが ... <使うユースケース> ・アプリケーション自体を異常終了させたい   ・configの読み込み、DB接続、などなど

  8. Goの常識 (型定義) ・単純なValueを持つStructならば、型を別名として再定義できる ・別の型なので、型システムの恩恵を受けられる ・型Aliasとはちょっと違う type Name struct { Value

    string } &Name{ Value: ”name” } type Name string Name(”name”)
  9. Goの常識 (型Alias) ・リファクタリングのための機能 ・NicePerson型は名前が違うだけでGoodPerson型と同一の型 reflect.TypeOf(GoodPerson{}) == reflect.TypeOf(NicePerson{}) はTRUE type GoodPerson

    struct{} type NicePerson = GoodPerson
  10. Goの常識 (書き方) ・型推論で変数を受け取る ・できるだけzero allocationを目指す(ベンチマークテストを書いても良い)

  11. ・ファイル名は全て小文字にし、複数の単語を利用する場合は snakeケースにする ・テストは同一パッケージ内に aiueo_test.goで作り、pkg_testパッケージにする ・コード整形はgo fmtコマンドによるFormatterに全てを委ねる ・パッケージレベルのアクセス修飾子だけを考えれば良い。頭文字大文字で public 小文字でprivate Goの常識

    (その他)
  12. Goの常識 (エラーハンドリング) Goでのエラーを扱うときに流派があり、それぞれ背景がある。 <前提> ・errorはinterfaceであり、`Error() string`を持つ全ての型はerrorになれる ・errorが発生する可能性がある関数は errorを返す

  13. Goの常識 (エラーハンドリング) ・エラーが発生しうる関数は多値で結果と errorを返すようにする ・呼び出し側が責任をもって errorを処理する func Divide(x, y int)

    (int, error) { if y == 0 { return 0, errors.New(“division by zero error”) } return x + y, nil }
  14. Goの常識 (エラーハンドリング) ・標準パッケージでの使われ方 ・エラーを値として定義する var NotFoundError = errors.New(”Not found error”)

    var EOFError = errors.New(”EOF error”)
  15. Goの常識 (エラーハンドリング) ・標準パッケージでの使われ方 ・エラーを型として定義する type NotFoundError struct { Err error

    Url string } func (n *NotFoundError) Error() string { return n.Url + ”:” + n.Err.Error() }
  16. Goの常識 (エラーハンドリング) ・エラーの返し方 ・そのまま返す results, err := doSomething() if err

    != nil { return nil, err }
  17. Goの常識 (エラーハンドリング) ・エラーの返し方 ・独自型にして返す path := ”http://example.com/” result, err :=

    GetResource(path) if err != nil { return nil, &NotFoundError{Url: path, Err: err} }
  18. Goの常識 (エラーハンドリング) ・エラーの比較 ・errorを型や値で比較する(エラー文字列で比較してはいけない)

  19. Goの常識 (エラーと向き合う) <現実問題> ・スタックトレース、どこでエラーになったのかが欲しい ・独自型を毎回作るのは辛い ・エラーの中身だけ取り出すの辛い ・結局最後は文字列やん?

  20. Goの常識 (エラーと向き合う) ・エラーと向き合うためのライブラリが発展する => https://github.com/pkg/errors  ・errors.Wrap()でエラーを装飾、errors.Cause()で中身を取り出す => https://github.com/golang/xerrors  ・(型の場合)Unwrap()で取り出し時、返却時にxerrors.Errorf(arg)で装飾  ・Is()を使ってエラーが含まれているか判断、

    As()をつかってエラーを取り出す => https://github.com/morikuni/failure  ・エラーコードなどで定義していく模様、 xerrorsのいいとこ取りしている
  21. よく使うライブラリ群(Backend API) 用途 ライブラリ おすすめ度 一言 Test https://github.com/stretchr/testify ★★★★★ 標準でgoのテストは書けなくなる

    DI https://github.com/google/wire ★★★★☆ google謹製の依存注入ライブラリ Error https://godoc.org/golang.org/x/xerrors ★★★☆☆ errorのwrapの仕組みを使える REST https://github.com/gin-gonic/gin ★★★★☆ Gin, Echoあたりがデファクト 標準のみでもOK conf https://github.com/spf13/viper ★★★☆☆ 素直なConfig読み込みが可能 ORM http://doc.gorm.io/ ★★★★☆ 高機能ORMでActiveRecord風
  22. たくさんあるライブラリ群 https://github.com/avelino/awesome-go