railsしかやって来なかった人のGoの基礎文法まとめ

#はじめに、、、
プログラミングをはじめて10ヶ月間railsしかやってこなかったのですが、、、　　
Goを実務で使うことになり大まかにですが基礎文法を軽く１周したのでそのまとめをしたいと思います。　　
#Hello World
```go
import "fmt"

func main() {
  fmt.Println("Hello World")
}

//〜出力〜
//Hello　World
```
golangは出力は基本的に ```fmt.Println``` を使うそうです。　　
またそのために ```"fmt"```をimportしなければいけません

#関数(func) ※Rubyだとdef
###引数なし

```go
import "fmt"

func hello() {
  fmt.Println("Hello World")
}

func main() {
  hello()
}

//〜出力〜
//Hello　World
```

###引数有り

```go
import "fmt"

func square(x int, y int) {
  fmt.Println(x*y)
}

func main() {
  square(5, 10)
}

//〜出力〜
//５０
```
引数の型名を宣言する必要がある。
また上のように引数の型が同じ場合下のようにも書ける

```go
func square(x, y int) {
  fmt.Println(x*y)
}
```

###返り値あり

```go
import "fmt"

func hello() string{
  return "Hello world"
}

func main() {
  fmt.Println(hello())
}

//〜出力〜
//Hello　World
```
返り値を返す場合は ```func 関数名（） 返す値の型``` というように書く必要がある

###jsの即時関数的な感じ

```go
import "fmt"

func main() {
  func (msg string) {
    fmt.Println(msg)
  }("Hello World")
}

//〜出力〜
//Hello　World
```

###変数に関数を入れる

```go
import "fmt"

func main() {
  h := func() {
    fmt.Println("Hello World")
  }
  h()
}

//〜出力〜
//Hello　World
```

#条件文
###if文
```go
import "fmt"

func main() {
  score := 70
  if 80 < score {
    fmt.Println("Great！")
  } else if 50 < score {
    fmt.Println("Good!")
  } else {
    fmt.Println("Bad")
  }
}

//〜出力〜
//Good!
```

###そのif文の中だけで評価する変数をつかう
```go
import "fmt"

func main() {
  if score := 70; 80 < score {
    fmt.Println("Great！")
  } else if 50 < score {
    fmt.Println("Good!")
  } else {
    fmt.Println("Bad")
  }

  fmt.Println(score)//⬅︎「score」っていう変数ないよ！っていうエラーがでる。
}

//〜出力〜
//Good!
```
###switch文
```go
import "fmt"

func main() {
  score := 70
  switch {
  case 80 < score:
    fmt.Println("Great！")
  case 50 < score:
    fmt.Println("Good!")
  default:
    fmt.Println("Bad")
  }
}

//〜出力〜
//Good!
```

#map※rubyだとハッシュ
```go
import "fmt"

func main() {
  m := map[int]string{1: "田中", 2: "鈴木", 3: "佐藤", 4: "渡辺"}
  fmt.Println(m)
  fmt.Println(m[1])
}

//〜出力〜
//map[1:田中 2:鈴木 3:佐藤 4:渡辺]
//田中
//4
```
mapの作り方としては ```map[キーの型]バリューの型```　と宣言して後はハッシュ（他の言語だと連想配列）と同じように宣言する。

#スライス※rubyだと配列
***注意！！！ Goにもスライスとは別に配列そのものは存在しますがGoでは配列とほぼ同じ使い方が出来てなおかつ使い勝手もいいスライスが使われることが多いみたいです（間違ってたら指摘お願いします。）なので最初はスライス==配列ということにします***



```go
import "fmt"

func main() {
  c := []int{1, 3, 7}
  fmt.Println(c)
}

//〜出力〜
//[1 3 7]
```
スライスの作り方としては ```[]配列の型{}``` として後はコロンで要素を区切って作る

#range※rubyだとeach文
```go
import "fmt"

func main() {
  s := []int{1, 3, 7}//スライスを作成
  
  for i, v := range s {
    fmt.Println(i, v)
  }
}

//〜出力〜
//0 1
//1 3
//2 7
```
rangeは返り値としてインデックス番号と値を返します。今回はiでインデックス番号、vで要素の値を受け取っています。
また仮に配列の要素のみ使いたい場合は ```for _, v := range c {```とする事でインデックス番号を無視してくれます

#for文
```go
import "fmt"

func main() {
  for i := 1; i < 100; i++ {
    fmt.Println(i)
  } 
}

//〜出力〜
//1
//2
//3
//・
//・
//・
//99


//条件をいれないと無限ループする
for {
  fmt.Println("Hello world")
}

//〜出力〜
//Hello world
//Hello world
//Hello world
//Hello world
//・
//・
//・
```
###while文っぽくもかける
でも、GOにwhile文は存在しない

```go
import "fmt"

func main() {
  sum := 1
  for sum < 30 {
    sum += sum
    fmt.Println(sum)
  }
}

//〜出力〜
//2
//4
//8
//16
//32
```

#構造体(struct)
イメージとしてはrailsのmodelみたいな感じ

```go
import "fmt"

//railsのmigration fileのように[カラム名 データ型]という形で定義　
type User struct {
  Name  string
  Age   int
}

func main() {
  //railsでデータをcreateするときのparamsと同じような形で定義
  user1 := User{Name: "kosuke", Age: 21}
  fmt.Println(user1)

  //そのデータに紐づく値を持ってくるときに 「.」区切りで値を参照できる
  fmt.Println(user1.Name)
  fmt.Println(user1.Age)
}

//〜出力〜
//{kosuke 21}
//kosuke
//21
```

ただ、↑でいっていることはあくまでイメージの話でgoの構造体はあくまでデータ型の１つであるのでその点は忘れないこと！

###構造体の値をメソッドを使って変える

```go
import "fmt"

type User struct {
  Name  string
  Age   int
}

func (u *User) changeName(string){
  u.Name = "Yamada"
}

func main() {
  user1 := User{Name: "kosuke", Age: 21}
  fmt.Println(user1.Name)

  user1.changeName(user1.Name)
  fmt.Println(user1.Name)
}

//〜出力〜
//kosuke
//Yamada
```
メソッドの定義方法は
```func (メソッド内での変数名 *構造体名) メソッド名(このメソッド内の引数の変数 引数のデータ型)```
 となっています。
また、重要なのは構造体名の前についている「*」でこれを書くことでポインタを渡すことができます。
ポインタってなんぞ？って人は下の記事が個人的にはわかりやすかったのでこちらを参照してください。

[【Go言語入門】構造体とポインタについて](https://qiita.com/To_BB/items/5b3625f8eca4f1c88574)

ざっくりとした認識としては
「とりあえず生成した構造体をメソッド使って値を変更させたいときは「*」つければいいんだな」  
って思っておけばいいと思います。

#インターフェース
```go
import "fmt"

//メソッド名(引数の型, ...) (返り値の型, ...)
type Human interface{
  Say() string
}

type Person struct {
  Name  string
}

func (u *Person) Say() string{
  u.Name = "Mr." + u.Name
  return u.Name
}

func main() {
  var user1 Human = &Person{Name: "kosuke"}
  fmt.Println(user1.Say())
}


//〜出力〜
//Mr.kosuke
```

インターフェイスとはメソッドの型です。
詳しくは↓
[【Golang】Golangのinterfaceで知っておくとお得なTips](https://qiita.com/romukey/items/e49e28b7dcf645ac91c7)


#並行処理
```go
import (
  "fmt"
  "time"
)

func hello()  {
  fmt.Println("hello")
}

func world()  {
  fmt.Println("world")
}

func main() {
  go hello()
  go world()

  time.Sleep(3 * time.Second)//3秒間動きを止める処理
}

//〜出力〜
//hello
//world

//または
//world
//hello
```
プログラムのコードは普通上から順番に読まれていきますが、Goでは
```go hogehoge```
とすることで同時に処理を行うことができます。
しかし、並行処理をしている間にプログラムそのものが終了してしまう可能性もあります。

それを回避するためには以下のように```"sync"```をimportして使用することで回避することができる

```go
import (
  "fmt"
  "sync"
)

func hello(wg *sync.WaitGroup)  {
  defer wg.Done()//deferはその関数内で一番最後に呼ばれるようにするメソッド
  fmt.Println("hello")
}
func world()  {
  fmt.Println("world")
}

func main() {
  var wg sync.WaitGroup
  wg.Add(1)

  go hello(&wg)
  go world()

  wg.Wait()//「wg.Done()」が呼ばれるまで処理をストップ
}
```