5分でわかるGo言語の文法まとめ

# Java経験者から見たGo言語の文法一覧
※2020年当時書いたものを掲載しているので、Javaの言語仕様の理解が古いかもしれません。。。
ご容赦ください。

## 文法規則
### 出力
```Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World");
    }
}
```

```main.go
package main
import (
	"fmt"
)
func main() {
	fmt.Println("Hello World")
}
```
※fmtパッケージが必要

### 変数
型は最後に書く ※varは変数、letは定数

```test.go
var c, python, java bool //c,python,javaは全てbool型
let swift bool = true //bool
```

★初期化すれば型を書かなくてよい

```test.go
var i, j int = 1, 2 // 型を指定
var c, python, java = true, false, "no!" // 型を指定しない
fmt.Println(i, j, c, python, java) //1, 2, true, false, "no!"
```
★変数をまとめられる

```test.go
var (
	ToBe   bool       = false
	MaxInt uint64     = 1<<64 - 1
	z      complex128 = cmplx.Sqrt(-5 + 12i)
)
const (
	pi = 3.14
	Big = 100
)
```

★初期化しなくても勝手に初期化してくれる

```test.java
//Javaの場合
int i;
System.out.println(i);//コンパイルエラー
```

```test.go
//Goの場合
var i int
var f float64
var b bool
var s string
fmt.Printf("%v %v %v %q\n", i, f, b, s)///0 0 false ""
```
★varを:=に省略できる。（ただし関数内のみ利用可。letでは使えない）

```test.go
var i = 1
x := 0　// エラー
func main() {
	let y := 3 // エラー
	j,k := 2,3
	fmt.Println(i, j, k)
}
```

### 関数
```test.java
public int add(int x,int y){
	return x + y;
}
```
```test.go
func add(x int, y int) int { 
	return x + y
}

func add(x, y int) int {
	return x + y
}
```
#### 2つ戻り値を返せる
```test.go
func swap(x, y string) (string, string) {
	return y, x
}
a, b := swap("hello", "world")
fmt.Println(a, b)// "world" "hello"
```
#### nakedReturn
戻り値に名前を設定できて、戻り値を指定しなくていい
※ただし、難読性につながるため、内部の処理が短い場合にのみ推奨

```test.go
func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return
}
```
### for文
```test.go
for i := 0; i < 10; i++ {
	sum += i
}
```
### while文

```test.go
sum := 1
for ; sum < 1000; {
	sum += sum
}

for sum < 1000 { //こっちの書き方でもOK
	sum += sum
}
```
### 無限ループ

```test.go
for {
}
```
### if文
```test.go
if x < 0 {
	return sqrt(-x) + "i"
}
```
★if文の評価直前に変数宣言できる（ただし、if・elseのスコープ内のみ有効）
```test.go
if v := math.Pow(x, n); v < lim {
	return v
} else {
	fmt.Printf("%g >= %g\n", v, lim)
}
	return lim //ここではvは使えない
```
### switch文
Javaと違い、caseに入ったらbreakされて止まる

```test.go
	switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		// freebsd, openbsd,
		// plan9, windows...
		fmt.Printf("%s.\n", os)
	}
```
### defer
周囲の関数が返ってくるまで実行されない

```test.go
defer fmt.Println("world")
fmt.Println("hello") // "hello world"
```

スタック形式で実行される last-in-first-out

```test.go
for i := 0; i < 10; i++ {
	defer fmt.Println(i)
}
fmt.Println("done") // "9" ,"8" , "7", ...
```

### Pointers
変数にポインタ(Javaでいうアドレス)を入れることができる

```test.go
	i, j := 42, 2701

	p := &i         // pのポインターにiのポインターを代入
	fmt.Println(p) // 0xc00002c008
	fmt.Println(*p) // 42
	*p = 21         // pの値に代入
	fmt.Println(i)  // 21

	p = &j         // point to j
	*p = *p / 37   // divide j through the pointer
	fmt.Println(j) // see the new value of j
```
Javaの場合、intは値型、Integerはクラス型(アドレス)と決まっていたが、
Goでは型を指定しない限り、値型(例　p := i) なのか クラス型(例 p := &i)なのかわからない。

### Struct
フィールドのコレクション

```test.go
type Vertex struct {
	X int
	Y int
}

func main() {
	v := Vertex{1, 2}
	fmt.Println(v) // {1, 2}

	v.X = 4
	fmt.Println(v.X) // "4"

	p := &v // ポインターをコピーすれば、シャローコピーできる
	p.X = 1e9
	fmt.Println(v） // 100000000, 2

	p  = &Vertex{1, 2} // &はstructのポインターが返される
	fmt.Println(p) // &{1, 2}
}
```


### ゴルーチン
力量が足りず、5分以内で説明できません。。。。申し訳ございません。