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

Javaプログラマのための頑張らないGo入門

yy_yank
November 23, 2019

 Javaプログラマのための頑張らないGo入門

2019年にJJUG CCC 2019 Fall で発表したものです(SlideShareからお引越し)。

yy_yank

November 23, 2019
Tweet

More Decks by yy_yank

Other Decks in Programming

Transcript

  1. ・イントロダクション(僕の思うGoとJava) 冒頭から含めて15分 ・Goことはじめ 7分 ・Goってこんなコード 9分 ・Goの特徴 10分 ・Go使いはじめ(yy_yank目線) 4.5分

    ・Goを使ってハマった編(yy_yank目線) 2分 ・まとめ 0.5分 アジェンダ 発表練習時 RTA(Real Time Attack)の結果です
  2. err := hoge(); if err != nil { log.Error(err) }

    Goってこんなコード ・if err != nil Goってこんなコード
  3. err := hoge(); if err != nil { log.Error(err) }

    Goってこんなコード ・if err != nil Goってこんなコード if err != nil でイディオムとして覚え て良いぐらい頻出
  4. if err := hoge(); err != nil { log.Error(err) }

    Goってこんなコード ・if err != nil Goってこんなコード または、ココでこう
  5. if err := hoge(); err != nil { log.Error(err) }

    Goってこんなコード ・if err != nil Goってこんなコード Exceptionない 例外機構ない err != nil、ただそれだけ
  6. if err := hoge(); err != nil { log.Error(err) }

    Goってこんなコード ・if err != nil Goってこんなコード pkg/errorsか xerrorsを使っていきましょう (今後は多分xerrors)
  7. if err := hoge(); err != nil { log.Error(err) }

    Goってこんなコード ・if err != nil Goってこんなコード errは関数の戻り値の 一番最後というキマリ↓ たとえば func makeStr() (string, error) 戻り値は多値に出来る
  8. if v, ok := m["a"]; ok { fmt.Printf("key=%v:value=%v", "a", v)

    } Goってこんなコード ・map Goってこんなコード contains的なのは こうやる
  9. hoges := []string{} hoges = append(hoges, “a”) hoges = append(hoges,

    “b”) hoges = append(hoges, “c”) fmt.Println(hoges) // => [a, b, c] Goってこんなコード ・slice append Goってこんなコード
  10. hoges := []string{} hoges = append(hoges, “a”) hoges = append(hoges,

    “b”) hoges = append(hoges, “c”) fmt.Println(hoges) // => [a, b, c] Goってこんなコード ・slice append Goってこんなコード これがslice
  11. hoges := []string{} hoges = append(hoges, “a”) hoges = append(hoges,

    “b”) hoges = append(hoges, “c”) fmt.Println(hoges) // => [a, b, c] Goってこんなコード ・slice append Goってこんなコード append….append...ap pend…..
  12. hoges := []string{} hoges = append(hoges, “a”) hoges = append(hoges,

    “b”) hoges = append(hoges, “c”) fmt.Println(hoges) // => [a, b, c] Goってこんなコード ・slice append Goってこんなコード sliceはざっくりいうと 可変配列のようなもの 配列を使った方が良い場合もあり。 カジュアルにappendしまくると計算量に よっては…(ご利用は計画的に)
  13. for _, hoge := range hoges { fmt.Print(hoge) } //

    => a b c Goってこんなコード ・range Goってこんなコード
  14. for _, hoge := range hoges { fmt.Print(hoge) } //

    => a b c Goってこんなコード ・range Goってこんなコード さっきのslice [a, b, c] です
  15. for _, hoge := range hoges { fmt.Print(hoge) } //

    => a b c Goってこんなコード ・range Goってこんなコード rangeで添字と要素を取 得できる _ で添字は無視、要素 のみhogeに格納
  16. for k, v := range m { fmt.Printf("key=%v:value=%v", k, v)

    } // => key=a:value=aaaa Goってこんなコード ・range Goってこんなコード
  17. for k, v := range m { fmt.Printf("key=%v:value=%v", k, v)

    } // => key=a:value=aaaa Goってこんなコード ・range Goってこんなコード さっきのmapのmさん [a:aaaa] です
  18. for k, v := range m { fmt.Printf("key=%v:value=%v", k, v)

    } // => key=a:value=aaaa Goってこんなコード ・range Goってこんなコード mapのkeyとvalueを 格納できます
  19. func deferSample() { defer fmt.Print("a") fmt.Print("b") fmt.Print("c") } // =>

    b c a Goってこんなコード ・defer Goってこんなコード
  20. func deferSample() { defer fmt.Print("a") fmt.Print("b") fmt.Print("c") } // =>

    b c a Goってこんなコード ・defer Goってこんなコード Javaで言うところのfinally deferでclose処理とかしたりする
  21. func highOrderFunc( beforeFunc func(), action func()) { beforeFunc() action() }

    Goってこんなコード ・高階関数 Goってこんなコード
  22. highOrderFunc( func() { fmt.Print("前処理") }, func() { fmt.Print("処理実行") }, )

    // => 前処理 処理実行 Goってこんなコード ・高階関数 Goってこんなコード
  23. highOrderFunc( func() { fmt.Print("前処理") }, func() { fmt.Print("処理実行") }, )

    // => 前処理 処理実行 Goってこんなコード ・高階関数 Goってこんなコード AOP的なことをやったりとか。 middlewareという 呼ばれ方が多い印象
  24. Goってこんなコード Goってこんなコード for _, sut := range []struct { value

    string description string }{ {value: "1", description: "1です"}, {value: "2", description: "2です"}, {value: "3", description: "3です"}, } { if !isNumeric(sut.value) { t.Errorf("expected number , but actual %s. test case :%s", sut.value, sut.description) } } ・テーブルドリブンテスト
  25. ・テーブルドリブンテスト Goってこんなコード Goってこんなコード for _, sut := range []struct {

    value string description string }{ {value: "1", description: "1です"}, {value: "2", description: "2です"}, {value: "3", description: "3です"}, } { if !isNumeric(sut.value) { t.Errorf("expected number , but actual %s. test case :%s", sut.value, sut.description) } } testケースをガッとまとめて (語彙力)
  26. ・テーブルドリブンテスト Goってこんなコード Goってこんなコード for _, sut := range []struct {

    value string description string }{ {value: "1", description: "1です"}, {value: "2", description: "2です"}, {value: "3", description: "3です"}, } { if !isNumeric(sut.value) { t.Errorf("expected number , but actual %s. test case :%s", sut.value, sut.description) } } ビャッと検証 (語彙力)
  27. Goってこんなコード ・goルーチン(めっちゃ雑) Goってこんなコード func main() { go job() // goルーチン

    // server起動処理など... // ... } goルーチン使ってjobを実行させ たりとかする
  28. package main import "fmt" func main() { fmt.Printf("Hello world\n") }

    Goの特徴(クロスコンパイル) ・hello worldやっときましょうか Goの特徴(クロスコンパイル)
  29. ・helloアプリケーションとかあるとすると、、 GOOS=linux GOARCH=amd64 go build hello.go GOOS=darwin GOARCH=amd64 go build

    hello.go GOOS=windows GOARCH=amd64 go build hello.go これを各OSの人たちに配ればOK Goの特徴(クロスコンパイル) Goの特徴(クロスコンパイル)
  30. ・文字列操作 stringsパッケージ、substring的なもの = rune ・文字列←→数値 strconv, fmt.Sprint ・文字列フォーマット fmt ・ソート

    sortパッケージ ・ファイルの読み書き ioutilパッケージ Javaで言うとこのアレ、ある? Go使いはじめ(Javaで言うところのアレ、ある?)
  31. ・LSP(Language Server Protocol) LSP仕様 https://github.com/Microsoft/language-server-protocol gopls一択の状況(旧名golsp)。 gopls のuser guide https://github.com/golang/tools/blob/master/gopls/doc/user.md

    goplsの他にbingoというのがあったが開発を止めてしまった … https://github.com/saibing/bingo gocodeも愛用されたがもう開発stop。。詳しくは https://mattn.kaoriya.net/software/lang/go/20181217000056.htm golang-serverも中身はgocodeらしいので…という話 まとめ ボツネタ
  32. ・業務アプリケーションの package構成について(個人的感覚) docker、k8s、istio、terraform、drone、prometheus などなどありますが 多分それをそのまま真似てもうまくいかない。 どういう方針でも自分たち考えて徐々に育てていくことが大事。 OSSのライブラリや SaaSとかIaaS的なものを作っている場合は真似しても良い気がするが、 実際自分たちが作っているのは何なのか …というところ。

    レイヤー分割バリバリするようなホニャララアーキテクチャも結構 Goは向いていない。 (かといってそれを実践している人たちを批判したいわけでもない )。 自動生成は受け入れやすいので自動生成系とフレームワークのルールに従う。 ライブラリを掛け合わせて最適化していくのが良いのかなと思いますが、 誰かの言葉を借りてそれを答えだと思わないで欲しいのでこれも答えではありません。 まとめ ボツネタ