rubyからgolangエンジニアへ

転職してgolangを触るようになり、３ヶ月経ったので一度ここで整理したいと思います。
前職ではrubyを6年間ぐらい触っていました。
rubyからgolangを触るようになって、学んだ事などをまとめていければと思います。

## 項目
1. go始めるにあたって
2. 定数定義
3. 継承
4. testの書き方
5. まとめ


## 1. go始めるにあたって
### 参考書籍
goを始めるにあたって、まず読んだ本はこの辺りです。
[改訂2版 みんなのGo言語   松木 雅幸](https://www.amazon.co.jp/dp/4297107279/ref=cm_sw_r_tw_dp_U_x_wu79DbNFQWN73)
[スターティングGo言語 (CodeZine BOOKS)   松尾 愛賀](https://www.amazon.co.jp/dp/4798142417/ref=cm_sw_r_tw_dp_U_x_wu79DbYM0ZQAF)

### 環境構築
有償にはなりますが、IDEは[Goland](https://www.jetbrains.com/ja-jp/go/)を使っています。
golangではgolandしか使った事ないので、比較が出来ないのですがプラグイン等いれてかなり快適になってきています。

こちらの記事を参考にlint辺りをいれています。
[GoLandでGo言語のLinterを設定する](https://qiita.com/m_nakamura145/items/a7ef77a41fba67205710)





## 2. 定数定義(iota)
定義あたりよく業務でも使うので記載してみたいと思います。
合わせて、iotaも使うと便利だったのでこちらも記載してみます。


普通に定数の定義しようと思ってrubyで書くとこのような感じになるかと思います。

```ruby
class Jiro
  module Topping
    YASAI   = 0
    NINNIKU = 1
    ABURA   = 2
  end
end
```

そのままgolangに書いてみるとこのようになります。

```golang
package jiro

const (
  ToppingYASAI   = 0
  ToppingNINNIKU = 1
  ToppingABURA   = 2
)
```
ただ、このようなインクリメントする場合にもう少しシンプルに書ける方法があって、それがiotaというの識別子です。

```golang
package jiro

const (
  ToppingYASAI   = iota // 0
  ToppingNINNIKU        // 1
  ToppingABURA          // 2
)
```

各定数に型(uint)を付けたい場合

```golang
package jiro

type JiroTopping uint

const (
  ToppingYASAI JiroTopping = iota // uint 0
  ToppingNINNIKU                  // uint 1
  ToppingABURA                    // uint 2
)
```

せっかくgolang使ってるので、定数にインクリメントしていく処理があれば、iota使ってみるのが良さそうです。

## 3. 継承
golangには継承は無く、業務で共通メソッドが欲しいなと思い調べてみたら、構造体をネストしてそれっぽく書くことができました。

```ruby
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
```

```ruby
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
=> "油マシマシ"
```

```golang
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](https://github.com/tomykaira/rspec-parameterized)を使ったような、テーブルドリブンテストで書くのが多いようです。（テーブルに各テスト項目を入れてeachでテストを回していく感じ）

```ruby
# main.rb
def generate_jumon(jumon_a, jumon_b)
  jumon_a+jumon_b
end
```

```ruby
# 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

```

```golang
// main.go
package main

func generateJumon(jumonA string, jumonB string) string {
  return jumonA + jumonB
}
```
```golang
// 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. まとめ
個人的に二郎が好きなので、サンプルコードが二郎ネタになっていてすみませんｗ
これからも、golang触ってみて学んだ事などを適宜まとめていければと思います。