Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

20161004 DMM/エウレカ/インテリジェンス合同勉強会

1,872 views

Published on

Go言語あるあるの解決方法や便利ツール・パッケージの紹介

Published in: Technology
  • Be the first to comment

20161004 DMM/エウレカ/インテリジェンス合同勉強会

  1. 1. Golang こんな時どうする? Yusuke Komatsu 2016-10-04.
 DMM.comラボ & eureka & インテリジェンス合同 Go言語勉強会
  2. 2. NULLを許容するDBやJSONって どうしよう? • ポインタを使う • sqlパッケージの型を使う(sql.NullString とか) • NULLなにそれ?おいしいの?
  3. 3. sql.Null** を使った場合 • sqlパッケージの中で実装されている • Nil判定もできるし、実態となる型はそのまま
 (Int64ならInt64で値が格納されている) • Scanを通せばある程度ゆるく解釈してくれる • 1変数内(構造体)に2つのパラメータが格納されてい て、両方見ないと値を取得できない 利点 欠点
  4. 4. ポインタを使った場合 • 数値や文字列などと一緒にNilを使える • Nilを区別しないで使うことができる • 通常の型として扱うには元に戻す必要がある • JsonなどをDecodeする時にゆるい解釈ができない
 (IntをStringとして解釈するなど) 利点 欠点
  5. 5. NULLを許容問題はRDBだけじゃない • 他のデータベースやキャッシュする際も考慮が必要 • jsonやXMLなどでも使う(特にAPI) • 他言語のプログラムと通信する場合も考える必要があ る
  6. 6. 便利な独自型つくりました
  7. 7. JSONのEncode/Decodeが直感的
  8. 8. 同じ値でもsetする型によって柔軟に解釈
  9. 9. 実は某社のAPIのレスポンスで事故ったので作った • 複数のサービスのデータを取りまとめられていて、サービスごとに型が バラバラ • int型のパラメータにstring型が混ざっていたりする • APIもPHPで、型やハッシュor配列判定を勝手に吸収して出力されている • 静的言語にとっては死亡フラグ こんな感じだったので またこんなことが起きても対処できるように作りました
  10. 10. genericはいろんな方のいいとこ取り • Scanが定義されているのでsqlパッケージでも意識せず使える • MarshalJSON / UnmarshalJSONを定義してるのでEncode/Decode時のNULL は自動的に考慮される • Set関数をつかえば、Nilを考えずに変数に値をセットできる • Value関数を使えば、1つだけ値が返ってくる(Nilの場合はNilが返ってくる) • 型判定の柔軟さはPHP並 • reflectはエラー時のみしか使ってない • sql.Null**型でやっているようなNULL判定も可能
  11. 11. 実はGo 2系でGenericsが実装されるかも
  12. 12. http.Response.Body 消失問題しってますか? • http.Response.Bodyを使いまわそうとしても1度 使うと空のio.ReadCloserになってしまう • 変数に入れ直しても変数も消える
  13. 13. こんなことはできません
  14. 14. こうしたら解決できる
  15. 15. みなさんテストってどうしてます? • とりあえずgo test?カバレッジとってる? • ソースの品質管理(担保)ってどうしてます? • そもそもテストしてますか?
  16. 16. リポジトリ内の全パッケージをテストしたい • リポジトリのルートディレクトリから再帰的にテスト • vendorディレクトリ配下はテストしたくない(glide nv) • 品質管理のためにカバレッジも取りたい(coverprofile) go test $(glide nv) -coverprofile=coverage.out ERROR: cannot use test profile flag with multiple packages
  17. 17. リポジトリ内の全パッケージをテストしたい ROOT_PATH="$GOPATH/src/seeds.rickcloud.jp/bitbucket/scm/hm/wage" COV_PARTIAL_FILE=profile.cov.out COV_FILE=profile-all.cov.out COV_MODE=count HEADER="mode: $COV_MODE" cd $ROOT_PATH; # テスト用DBのマイグレーション goose -env testing up; echo "mode: count" > $COV_FILE # ひつようのないディレクトリを除いたディレクトリを再帰的にチェック for dir in $(find . -maxdepth 10 -not -path './.git*' -not -path '*/_*' -not -path './cmd' -not -path './release*' -not -path './vendor*' -type d) do if ls $dir/*.go &> /dev/null; then # 個々にテストをして一時保存用プロフィールに保存 go test -v -covermode=count -coverprofile=$dir/$COV_PARTIAL_FILE $dir if [ -f $dir/$COV_PARTIAL_FILE ]; then # 一時保存されたものを出力用プロファイルに転記 cat $dir/$COV_PARTIAL_FILE | tail -n +2 >> $COV_FILE rm $dir/$COV_PARTIAL_FILE fi fi done # テスト用DBのロールバック goose -env testing down;
  18. 18. ソースコードの品質管理 • gofmt (インストール不要)
 ソースコードを整形する • go_vet (インストール不要)
 コンパイルエラーにならないヒューリスティックな問題を検出する • gocyclo (https://github.com/fzipp/gocyclo)
 循環的複雑度(コードの複雑性)の検証をする • glint (https://github.com/golang/lint)
 Golangのlinter • ineffassign (https://github.com/gordonklaus/ineffassign)
 無駄な割当を検出する • misspell (https://github.com/client9/misspell)
 スペルミスを検出する
  19. 19. ソースコードの品質管理
  20. 20. ソースコードの品質管理
  21. 21. THANK YOU!! [generics] • usk81/generic https://github.com/usk81/generic • proposal: generic programming facilities https://github.com/golang/go/issues/15292 [test] • Go Report Card https://goreportcard.com

×