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

69

Published on

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

Published in: Software
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
69
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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!
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×