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.
Javaプログラマ向けGoガイド
Seasar Conference 2015
2015/09/26
米 林 正 明 @yone098
自己紹介
 米 林 正 明
 @yone098
 株式会社Abby(エビイ) 代表取締役
はじめに
 私とGo
 約1年 サーバサイドAPI
 今一番好きな言語
 Eclipse は数ヶ月起動していない
 わからない事は?
全部@mopemopeに聞けばいい
 対象
 Goに興味があるJavaプログラマ
 Goを少...
agenda
 はじめに
 JavaからGoへ
 Go開発事例
 おわりに
Goとは
 静的型付けコンパイル言語
 C言語に近くLLではない
 継承がない
 ジェネリクスがない
 例外がない
 ライブラリのバージョン指定がない
Goとは
 静的型付けコンパイル言語
 C言語に近くLLではない
 継承がない
 ジェネリクスがない
 例外がない
 ライブラリのバージョン指定がない
 でも「まんまん満足!」
Goとは
 静的型付けコンパイル言語
 C言語に近くLLではない
 継承がない
 ジェネリクスがない
 例外がない
 ライブラリのバージョン指定がない
 でも「まんまん満足!」
 いいところ満載
JavaからGoへ
JavaからGoへ
 LLではないがLLに近い実行方法
 コンパイルと同時に実行出来る
 javac と java コマンドの合わせ技
$ go run main.go
package main
import (
"fmt"
)
func...
JavaからGoへ
 LLではないがLLに近い実行方法
 コンパイルと同時に実行出来る
 javac と java コマンドの合わせ技
$ go run main.go
package main
import (
"fmt"
)
func...
JavaからGoへ
 LLではないがLLに近い実行方法
 コンパイルと同時に実行出来る
 javac と java コマンドの合わせ技
$ go run main.go
package main
import (
"fmt"
)
func...
JavaからGoへ
 Java : classpath
 Go : $GOPATH
 go get で install
$ go get github.com/zenazn/goji
bin/
pkg/
src/
github.com/z...
JavaからGoへ
 Java : classpath
 Go : $GOPATH
 go get で install
$ go get github.com/zenazn/goji
bin/
pkg/
src/
github.com/z...
JavaからGoへ
 package
 名前とモジュール管理 import パッケージ
 重複時 Go : alias
 重複時 Java : パッケージ名 + class名
package main
import (
"log" //...
JavaからGoへ
 package
 名前とモジュール管理 import パッケージ
 重複時 Go : alias
 重複時 Java : パッケージ名+class名
package main
import (
"log" // l...
JavaからGoへ
 アクセス指定子
 Java : private, public
 Go : 大文字・小文字
package main
import (
"./sub"
"fmt"
)
func main() {
fmt.Printl...
JavaからGoへ
 アクセス指定子
 Java : private, public
 Go : 大文字・小文字
package main
import (
"./sub"
"fmt"
)
func main() {
fmt.Printl...
JavaからGoへ
 interface
 Java : implements
 Go : メソッド定義
 メソッド定義でどんなオブジェクトでも代入可能
package main
func say(yone Yone) {
fmt.Pr...
JavaからGoへ
 cast
 Java : (データ型)式 or ジェネリクス
 Go : 型アサーション 式.(データ型)
var i interface{} = "hoge”
if s, ok := i.(string); ok ...
JavaからGoへ
 cast
 Java : (データ型)式 or ジェネリクス
 Go : 型アサーション
var i interface{} = "hoge”
if s, ok := i.(string); ok {
fmt.Pri...
JavaからGoへ
 例外
 Java : Exception, try-catch
 Go : 無し!とにかく if err != nil
 常にエラーを返す
err := func1()
if err != nil {
// エラー...
JavaからGoへ
 例外
 Java : Exception, try-catch
 Go : 無し!とにかく if err != nil
 常にエラーを返す
err := func1()
if err != nil {
// エラー...
JavaからGoへ
 例外
 Java : Exception, try-catch
 Go : 無し!とにかく if err != nil
 常にエラーを返す
err := func1()
if err != nil {
// エラー...
JavaからGoへ
 戻り値
 Java : 単一
 Go : 多値
 受け取り無視にはブランク識別子
val, err := sum(1, 2)
if err != nil {
// エラー処理
}
val, _, _, err = ...
JavaからGoへ
 戻り値
 Java : 単一
 Go : 多値
 受け取り無視にはブランク識別子
val, err := sum(1, 2)
if err != nil {
// エラー処理
}
val, _, _, err = ...
JavaからGoへ
 資源解放
 Java : try-finally
 Go : defer
func finally() {
fmt.Println("finally")
}
func main() {
defer finally()...
JavaからGoへ
 資源解放
 Java : try-finally
 Go : defer
func finally() {
fmt.Println("finally")
}
func main() {
defer finally()...
JavaからGoへ
 初期化子
 Java : staticイニシャライザ
 Go : init()
package sub
import (
"fmt"
)
func init() {
fmt.Println("sub init()")...
JavaからGoへ
 初期化子
 Java : staticイニシャライザ
 Go : init()
package sub
import (
"fmt"
)
func init() {
fmt.Println("sub init()")...
JavaからGoへ
 配布形式
 Java : jar, war
 配布には必要ライブラリを含める
 Go : 単一の実行可能ファイル
 クロスコンパイル
GOOS=windows GOARCH=amd64 go build -o s...
JavaからGoへ
 配布形式
 Java : jar, war
 配布には必要ライブラリを含める
 Go : 単一の実行可能ファイル
 クロスコンパイル
配布がとくかく容易
GOOS=windows GOARCH=amd64 go ...
JavaからGoへ
 本番と開発の設定変更
 Java : profile(maven, Spring Boot)
 Go : tag
go build –tags release
// +build !release
package e...
JavaからGoへ
 アノテーション
 Java : annotasion
 Go : tag
type Person struct {
Id int64 `json:"code"`
Name string `json:“name“`
A...
JavaからGoへ
 Test
 Java : JUnit
 Assert
 Go : testing
 Assertは無い, if文で
 ソースファイルと同一パッケージ
 calc.go なら calc_test.go
func...
JavaからGoへ
 コード整形
 Java : IDE
 Go : gofmt, goimports
 公式サポート
 コードの統一
 golint, go vet でチェック
JavaからGoへ
 依存関係
 Java : gradle, maven
 Go : godep, gb, vendor
 バージョン指定が出来ない
 マルチプロジェクトで困る
 $GOPATH/src以下にfetch
 Go1...
JavaからGoへ
 Javaプログラマ向けチートシート
 javac->java : go run
 classpath : $GOPATH
 import : import
 public, private : 大文字・小文字
...
Go開発事例
Go開発事例
 ムーミン APIサーバ
 Go1.4
 goji
 godep, fresh
 drone slack通知 成果物dropbox
 DDLをbranch毎
 goconvey カバレッジ
 circus
 ng...
Go開発事例
 最新
 Go1.5
 goji, gorm, pq
 gb, goemon, goconvey
 drone slack通知 成果物dropbox
 nginx
 postgresql
 Redis Pub/Su...
終わりに
終わりに
 みんなもGoやろう!
 プロダクトで使ってみた感想
 JavaプログラマにはGoは向いていると思う!
 これからもGoを採用していく予定
 Go1.5
 期待!
おまけ
Goよりも
普通に
Ingressが好き💙
Thank you!
Upcoming SlideShare
Loading in …5
×

Go guide for Java programmer

6,487 views

Published on

Seasar conference 2105
Javaプログラマ向けGoガイド

Published in: Software
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Go guide for Java programmer

  1. 1. Javaプログラマ向けGoガイド Seasar Conference 2015 2015/09/26 米 林 正 明 @yone098
  2. 2. 自己紹介  米 林 正 明  @yone098  株式会社Abby(エビイ) 代表取締役
  3. 3. はじめに  私とGo  約1年 サーバサイドAPI  今一番好きな言語  Eclipse は数ヶ月起動していない  わからない事は? 全部@mopemopeに聞けばいい  対象  Goに興味があるJavaプログラマ  Goを少し触ったことがある人
  4. 4. agenda  はじめに  JavaからGoへ  Go開発事例  おわりに
  5. 5. Goとは  静的型付けコンパイル言語  C言語に近くLLではない  継承がない  ジェネリクスがない  例外がない  ライブラリのバージョン指定がない
  6. 6. Goとは  静的型付けコンパイル言語  C言語に近くLLではない  継承がない  ジェネリクスがない  例外がない  ライブラリのバージョン指定がない  でも「まんまん満足!」
  7. 7. Goとは  静的型付けコンパイル言語  C言語に近くLLではない  継承がない  ジェネリクスがない  例外がない  ライブラリのバージョン指定がない  でも「まんまん満足!」  いいところ満載
  8. 8. JavaからGoへ
  9. 9. JavaからGoへ  LLではないがLLに近い実行方法  コンパイルと同時に実行出来る  javac と java コマンドの合わせ技 $ go run main.go package main import ( "fmt" ) func main() { fmt.Println("SeasarCon2015") }
  10. 10. JavaからGoへ  LLではないがLLに近い実行方法  コンパイルと同時に実行出来る  javac と java コマンドの合わせ技 $ go run main.go package main import ( "fmt" ) func main() { fmt.Println("SeasarCon2015") } $ go run main.go SeasarCon2015
  11. 11. JavaからGoへ  LLではないがLLに近い実行方法  コンパイルと同時に実行出来る  javac と java コマンドの合わせ技 $ go run main.go package main import ( "fmt" ) func main() { fmt.Println("SeasarCon2015") } $ go run main.go SeasarCon2015 取り急ぎやってごらん
  12. 12. JavaからGoへ  Java : classpath  Go : $GOPATH  go get で install $ go get github.com/zenazn/goji bin/ pkg/ src/ github.com/zanazn/goji bitbucket.org/… golang.org/…
  13. 13. JavaからGoへ  Java : classpath  Go : $GOPATH  go get で install $ go get github.com/zenazn/goji bin/ pkg/ src/ github.com/zanazn/goji bitbucket.org/… golang.org/… your_project/ .m2repo配下で開発するイメージ
  14. 14. JavaからGoへ  package  名前とモジュール管理 import パッケージ  重複時 Go : alias  重複時 Java : パッケージ名 + class名 package main import ( "log" // logを取り込む "github.com/zenazn/goji" // gojiを取り込む mylog “myproject/log” // 自作logを取り込む ) func main() { mylog.Debugf("Go!") ... }
  15. 15. JavaからGoへ  package  名前とモジュール管理 import パッケージ  重複時 Go : alias  重複時 Java : パッケージ名+class名 package main import ( "log" // logを取り込む "github.com/zenazn/goji" // gojiを取り込む mylog “myproject/log” // 自作logを取り込む ) Javaのようにコンパイル時にライブラリ指定が不 要でありソースコードで依存関係を明確にする
  16. 16. JavaからGoへ  アクセス指定子  Java : private, public  Go : 大文字・小文字 package main import ( "./sub" "fmt" ) func main() { fmt.Println(sub.Func1()) fmt.Println(sub.func2()) // NG } package sub func Func1() string { return "Func1" } func func2() string { return "func2" }
  17. 17. JavaからGoへ  アクセス指定子  Java : private, public  Go : 大文字・小文字 package main import ( "./sub" "fmt" ) func main() { fmt.Println(sub.Func1()) fmt.Println(sub.func2()) // NG } package sub func Func1() string { return "Func1" } func func2() string { return "func2" } 基本、メソッドやメンバは大文字から始めパッ ケージ外に公開したくない場合は小文字ちゃん
  18. 18. JavaからGoへ  interface  Java : implements  Go : メソッド定義  メソッド定義でどんなオブジェクトでも代入可能 package main func say(yone Yone) { fmt.Println(yone.hello()) } func main() { var mope Mope say(mope) } type Yone interface { hello() string } type Mope struct{} func (_ Mope) hello() string { return "mope" }
  19. 19. JavaからGoへ  cast  Java : (データ型)式 or ジェネリクス  Go : 型アサーション 式.(データ型) var i interface{} = "hoge” if s, ok := i.(string); ok { fmt.Println("String: ", s) } else { fmt.Println("Not String” , s) }
  20. 20. JavaからGoへ  cast  Java : (データ型)式 or ジェネリクス  Go : 型アサーション var i interface{} = "hoge” if s, ok := i.(string); ok { fmt.Println("String: ", s) } else { fmt.Println("Not String") } iがstringであればsに変換結果, okにはtrueがセットされる。 そうでなければsにstring初期値, okにはfalseがセットされる。 okを指定せず戻り値をsだけにして型アサーションした場合には型変 換に失敗した場合にはランタイムパニックになる。
  21. 21. JavaからGoへ  例外  Java : Exception, try-catch  Go : 無し!とにかく if err != nil  常にエラーを返す err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 }
  22. 22. JavaからGoへ  例外  Java : Exception, try-catch  Go : 無し!とにかく if err != nil  常にエラーを返す err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 }
  23. 23. JavaからGoへ  例外  Java : Exception, try-catch  Go : 無し!とにかく if err != nil  常にエラーを返す err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } err := func1() if err != nil { // エラー処理 } err = func2() if err != nil { // エラー処理 } err = func3() if err != nil { // エラー処理 } err = func4() if err != nil { // エラー処理 } これがGoだ!これがGoだ!これがGoだ!これがGoだ!これがGo だ!これがGoだ!これがGoだ!これがGoだ!これがGoだ!これが
  24. 24. JavaからGoへ  戻り値  Java : 単一  Go : 多値  受け取り無視にはブランク識別子 val, err := sum(1, 2) if err != nil { // エラー処理 } val, _, _, err = func2() if err != nil { // エラー処理 }
  25. 25. JavaからGoへ  戻り値  Java : 単一  Go : 多値  受け取り無視にはブランク識別子 val, err := sum(1, 2) if err != nil { // エラー処理 } val, _, _, err = func2() if err != nil { // エラー処理 } 値の受け取りを無視しても良いが戻り値のerrをブランク識別子で受けて はダメなんだぞぉ〜。Javaのtry-catchで処理を書かないことと同じ!
  26. 26. JavaからGoへ  資源解放  Java : try-finally  Go : defer func finally() { fmt.Println("finally") } func main() { defer finally() for i := 0; i < 10; i++ { fmt.Println("i:", i) } }
  27. 27. JavaからGoへ  資源解放  Java : try-finally  Go : defer func finally() { fmt.Println("finally") } func main() { defer finally() for i := 0; i < 10; i++ { fmt.Println("i:", i) } } deferは関数終了時にコールされる。 複数deferを登録すると最後に登録したdeferから実行される。 $ go run main.go i: 0 i: 1 i: 2 i: 3 i: 4 i: 5 i: 6 i: 7 i: 8 i: 9 finally
  28. 28. JavaからGoへ  初期化子  Java : staticイニシャライザ  Go : init() package sub import ( "fmt" ) func init() { fmt.Println("sub init()") } func Func1() { fmt.Println("Func1") } package main import ( "./sub" "fmt" ) func main() { fmt.Println("SeasarCon2015") sub.Func1() }
  29. 29. JavaからGoへ  初期化子  Java : staticイニシャライザ  Go : init() package sub import ( "fmt" ) func init() { fmt.Println("sub init()") } func Func1() { fmt.Println("Func1") } 初期化関数はmain関数の定義されたソースから連鎖的にimportされた パッケージのみのため予期せず使用しないソースのinitは実行されない package main import ( "./sub" "fmt" ) func main() { fmt.Println("SeasarCon2015") sub.Func1() }
  30. 30. JavaからGoへ  配布形式  Java : jar, war  配布には必要ライブラリを含める  Go : 単一の実行可能ファイル  クロスコンパイル GOOS=windows GOARCH=amd64 go build -o seasar.exe GOOS=darwin GOARCH=amd64 go build -o seasar GOOS=linux GOARCH=amd64 go build -o seasar
  31. 31. JavaからGoへ  配布形式  Java : jar, war  配布には必要ライブラリを含める  Go : 単一の実行可能ファイル  クロスコンパイル 配布がとくかく容易 GOOS=windows GOARCH=amd64 go build -o seasar.exe GOOS=darwin GOARCH=amd64 go build -o seasar GOOS=linux GOARCH=amd64 go build -o seasar
  32. 32. JavaからGoへ  本番と開発の設定変更  Java : profile(maven, Spring Boot)  Go : tag go build –tags release // +build !release package env const DEBUG = true // +build release package env const DEBUG = false env.go env_release.go if env.DEBUG { log.Println(”debug print") }
  33. 33. JavaからGoへ  アノテーション  Java : annotasion  Go : tag type Person struct { Id int64 `json:"code"` Name string `json:“name“` Age int `json:“age"` CreatedAt int64 }
  34. 34. JavaからGoへ  Test  Java : JUnit  Assert  Go : testing  Assertは無い, if文で  ソースファイルと同一パッケージ  calc.go なら calc_test.go func TestSum(t *testing.T) { actual := Sum(1, 2) expected := 3 if actual != expected { t.Errorf(”actual %v expected %v", actual, expected) } }
  35. 35. JavaからGoへ  コード整形  Java : IDE  Go : gofmt, goimports  公式サポート  コードの統一  golint, go vet でチェック
  36. 36. JavaからGoへ  依存関係  Java : gradle, maven  Go : godep, gb, vendor  バージョン指定が出来ない  マルチプロジェクトで困る  $GOPATH/src以下にfetch  Go1.5 Vendoring!
  37. 37. JavaからGoへ  Javaプログラマ向けチートシート  javac->java : go run  classpath : $GOPATH  import : import  public, private : 大文字・小文字  implements : メソッド定義  (データ型)式 : v, ok := 式.(データ型)  例外あり : 例外無し if err != nil  単一を返す : 多値を返せる  try-finally : defer  static{} : init()  jar, war : クロスコンパイル  profile : -tags  @annotation : タグ  JUnit : testing  IDE : gofmt, goimports  gradle, maven : godep, gb, vendor
  38. 38. Go開発事例
  39. 39. Go開発事例  ムーミン APIサーバ  Go1.4  goji  godep, fresh  drone slack通知 成果物dropbox  DDLをbranch毎  goconvey カバレッジ  circus  nginx  mysql join禁止  log LTSV, Elasticsearch, kibana  管理画面  @mopeomope
  40. 40. Go開発事例  最新  Go1.5  goji, gorm, pq  gb, goemon, goconvey  drone slack通知 成果物dropbox  nginx  postgresql  Redis Pub/Sub  websocket
  41. 41. 終わりに
  42. 42. 終わりに  みんなもGoやろう!  プロダクトで使ってみた感想  JavaプログラマにはGoは向いていると思う!  これからもGoを採用していく予定  Go1.5  期待!
  43. 43. おまけ Goよりも 普通に Ingressが好き💙
  44. 44. Thank you!

×