転職してgolangを触るようになり、3ヶ月経ったので一度ここで整理したいと思います。
前職ではrubyを6年間ぐらい触っていました。
rubyからgolangを触るようになって、学んだ事などをまとめていければと思います。
項目
- go始めるにあたって
- 定数定義
- 継承
- testの書き方
- まとめ
1. go始めるにあたって
参考書籍
goを始めるにあたって、まず読んだ本はこの辺りです。
改訂2版 みんなのGo言語 松木 雅幸
スターティングGo言語 (CodeZine BOOKS) 松尾 愛賀
環境構築
有償にはなりますが、IDEはGolandを使っています。
golangではgolandしか使った事ないので、比較が出来ないのですがプラグイン等いれてかなり快適になってきています。
こちらの記事を参考にlint辺りをいれています。
GoLandでGo言語のLinterを設定する
2. 定数定義(iota)
定義あたりよく業務でも使うので記載してみたいと思います。
合わせて、iotaも使うと便利だったのでこちらも記載してみます。
普通に定数の定義しようと思ってrubyで書くとこのような感じになるかと思います。
class Jiro
module Topping
YASAI = 0
NINNIKU = 1
ABURA = 2
end
end
そのままgolangに書いてみるとこのようになります。
package jiro
const (
ToppingYASAI = 0
ToppingNINNIKU = 1
ToppingABURA = 2
)
ただ、このようなインクリメントする場合にもう少しシンプルに書ける方法があって、それがiotaというの識別子です。
package jiro
const (
ToppingYASAI = iota // 0
ToppingNINNIKU // 1
ToppingABURA // 2
)
各定数に型(uint)を付けたい場合
package jiro
type JiroTopping uint
const (
ToppingYASAI JiroTopping = iota // uint 0
ToppingNINNIKU // uint 1
ToppingABURA // uint 2
)
せっかくgolang使ってるので、定数にインクリメントしていく処理があれば、iota使ってみるのが良さそうです。
3. 継承
golangには継承は無く、業務で共通メソッドが欲しいなと思い調べてみたら、構造体をネストしてそれっぽく書くことができました。
class Jiro
def rand_jumon
%w("野菜マシマシ" "野菜ニンニクからめ" "油マシマシ").sample
end
end
class Pjiro < Jiro
attr :store_name
def initialize
@store_name = "Pjiro"
end
end
class Sjiro < Jiro
attr :store_name
def initialize
@store_name = "Sjiro"
end
end
irb(main):034:0> p = Pjiro.new
=> #<Pjiro:0x00007ff6bc8b53e8 @title="Pjiro">
irb(main):035:0> p.rand_jumon
=> "野菜ニンニクからめ"
irb(main):037:0> s = Sjiro.new
=> #<Pjiro:0x00007ff6ce90f200 @title="Sjiro">
irb(main):038:0> p.rand_jumon
=> "油マシマシ"
import(
"fmt"
)
type Jiro struct {}
func (j *Jiro) RandJumon() string {
return "aaa"
randInt = rand.Intn(2)
switch randInt {
case 0:
return "野菜マシマシ"
case 1:
return "野菜ニンニクからめ"
case 2:
return "油マシマシ"
}
}
type Pjiro struct {
// Jiroをネスト
Jiro
storeName string
}
type Sjiro struct {
// Jiroをネスト
Jiro
storeName string
}
func main() {
pjiro := &Pjiro{
storeName: "pjiro",
}
fmt.Printf("%#v", pjiro.RandJumon())
}
4. testの書き方
golangでのテストは、rubyでいうrspec-parameterizedを使ったような、テーブルドリブンテストで書くのが多いようです。(テーブルに各テスト項目を入れてeachでテストを回していく感じ)
# main.rb
def generate_jumon(jumon_a, jumon_b)
jumon_a+jumon_b
end
# main_spec.rb
describe "squre" do
where(:jumon_a, :jumon_b, :generate_jumon) do
[
["野菜マシ", "にんにく", "野菜マシにんにく"],
["にんにく", "カラメ", "にんにくカラメ"],
]
end
with_them do
it "#{jumon_a} + #{jumon_b} = #{generate_jumon}" do
expect(generate_jumon(jumon_a, jumon_b)).to eq generate_jumon
end
end
end
// main.go
package main
func generateJumon(jumonA string, jumonB string) string {
return jumonA + jumonB
}
// main_test.go
package main
import(
"testing"
)
func TestGenerateJumon(t *testing.T){
tests := []struct{
jumonA string,
jumonB string,
want string
}{
{"野菜マシ", "にんにく", "野菜マシにんにく"},
{"にんにく", "カラメ", "にんにくカラメ"},
}
for _, t := range tests {
if got := generateJumon(t.jumonA, t.jumonB); got != t.want {
t.Fatalf("want = %s, got = %s", t.want, got)
}
}
}
あとrubyと違うところとして、rspecだとspec/*/*/xx_spec.rb
のように、spec配下にテストコードを入れるようになってますが、golangだと、テスト対象のファイルと同じ階層にテストコードもいれるようになっています。
src/domain/jiro.go // テスト対象ファイル
jiro_test.go // テストコード
5. まとめ
個人的に二郎が好きなので、サンプルコードが二郎ネタになっていてすみませんw
これからも、golang触ってみて学んだ事などを適宜まとめていければと思います。