Golangのチュートリアル

## 必要事項

- golang 1.9のインストール
- VSCode

## golangの基礎

directoryを適当に作成してmainファイルを作成します。

```
mkdir go-tutorial
cd go-tutorial && touch main.go

```

今回はそのディレクトリプロジェクトのrootディレクトリにしたのでそのディレクトリのパスを通します。


```
go mod init example/hello
```

### 表示させる

まずはどの言語でもやるHello Worldから
goはprintさせるだけでもfmtライブラリーをインストールする必要があります。

実際に作ってみましょう。

Vscodeでプロジェクトのディレクトリを指定して開いてmain.goに以下のコードをコピペしてください。

```golang:main.go
package main

import (
	"fmt"
)

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


```
下のコマンドを呼び出して動けば成功です。

```
go run ./
```

### 定数と変数

まずは定数からやります。

定数とは変数ととは違い一度値が決まったら変更できない値です。

golangでは下のように記述します

```golang
const MAX_VALUE = 100
```

次に変数を使ってみます。

```golang
var MAX_VALUE = 100
```

試しに変数を変更してみましょう。

```golang
package main

import (
	"fmt"
)

func main() {
    // 200としてセット
	var MAX_VALUE = 200
	fmt.Println(MAX_VALUE)
　　// 300に変更
	MAX_VALUE = 300
	fmt.Println(MAX_VALUE)
}
```

## Data Type

Golangはポインタや構造体など一部をのぞいて他の言語と変わらないので知りたい方はChatGPTで作ったのでそれを参照してください。

```go
package main

import "fmt"

func main() {
   var integer int = 2021
   var float float64 = 3.14
   var boolean bool = true
   var str string = "Golang Programming"
   
   fmt.Printf("Integer Value: %d \n", integer)
   fmt.Printf("Float Value: %f \n", float)
   fmt.Printf("Boolean Value: %t \n", boolean)
   fmt.Printf("String Value: %s \n", str)
  
   //Creating an array
   var arr [3]int
   arr[0] = 1
   arr[1] = 2
   arr[2] = 3
   
   fmt.Println("Array:", arr)
   
  //Creating a slice
  var slic []int = arr[0:2]
  slic[0] = 100
  
  //Printing changed array and slice
  fmt.Println("After Updating:")
  fmt.Println("Array:", arr)
  fmt.Println("Slice:", slic)
  
  //Creating a map
  var m map[string]int = map[string]int{"one": 1, "two": 2, "three": 3}
  fmt.Println("Map:", m)
  
  //Creating a struct
  type Student struct {
    name string
    age int
    grade float32
  }
  
  var student1 Student = Student{name: "John", age: 20, grade: 3.5}
  fmt.Println("Student1:", student1)
  
  //Creating a pointer
  var ptr *int = &integer
  fmt.Println("Pointer Value:", ptr)
  
  //Creating an interface
  type Shape interface {
    Area() float64
  }
  
}
```

## 関数

### 関数を実際に作ってみる

Golangの関数は下のコードに

- 関数名(functionName)
- 引数(parameters)
- returnするときのタイプ(returnType)

を指定して処理を書きます。

```golang
func functionName(parameters) returnType {
  // ここに処理を書いてresultに値をいれる
  return result
}

```

### 匿名関数

すみません。日本語で何ていうのかわからないので直訳しました(笑)

匿名関数が名前の通り関数名がなく、その場ですぐに呼ばれる関数のことです。

```go
package main

import "fmt"

func main() {
	// "Hello, World!"と表示する匿名関数
	func() {
		fmt.Println("Hello, World!")
	}()

	// 掛け算を行う匿名関数
	result := func(x, y int) int {
		return x * y
	}(5, 10)
	fmt.Println(result)
}

```

### 再帰

再帰とは関数内の処理で同じ関数を条件に当てはまるまで呼び続けること

例えば下の例ではnが0になるまで呼び出し続けている

```golang
func fact(n int) int {
    if n == 0 {
        return 1
   }
    return n * fact(n-1)
}
```

returnが複数の時

```go
func swap(x, y string) (string, string) {
  return y, x
}

a, b := swap("hello", "world")
fmt.Println(a, b)
```

## ポインタの基礎

ポインタは変数のメモリアドレスを格納する変数です。

つまり、ポインタはデータを直接格納するのではなく、コンピュータのメモリにデータが格納されている場所を指定します

### どんな時の使うか？

ポインタを使うべきところは主に2つあります。
1つ目は大きなデータを変数に格納したい場合です。

大きなデータを変数に入れてしまうと変数が使われるたびにデータがコピーされてしまうため、負荷を考えると大きなデータや使い回すデータはなるべくポインタにするべきです。

もう一つはstructなどを使う時です。

Golangでは、ポインタというものを使って、structやオブジェクトを扱うことができます。structを箱のように考えて、その中にいろいろなものを入れて、その箱の中の何かを変えたいとします。

ポインターを使うと、値を直接保持するのではなく、メモリ上の箱の正確な位置を指し示す特殊な変数を作ることができます。このポインタ変数を関数に渡すと、ポインタ変数が指すstructに変更を加えることができ、その変更は元のstructに反映されます。

これは、二人の人間が同じ箱を持っているようなもので、一人が箱の中の何かを動かすと、もう一人にもその変化がわかるようになっています。

ですから、ポインターは、struct全体をコピーすることなく、structの中のものを変更したいときにとても便利です。元の箱へのショートカットを持つようなもので、より速く、より効率的に変更を加えることができるのです。

### ポインタの使用例

```golang
package main

import "fmt"

type Person struct {
	name string
	age  int
}

func main() {
	p := Person{name: "Alice", age: 30}

	// 構造体のポインタを作成する
	ptr := &p
	fmt.Println(ptr) //&{Alice 30}

	// 構造体のポインタを使って構造体の値を取得する
	fmt.Println((*ptr).name) // prints "Alice"
	fmt.Println(ptr.age)     // prints 30

	// pointerを使ってpの値を変更する
	ptr.name = "Bob"
	ptr.age = 35
	fmt.Println(p) // prints "{Bob 35}"
}

```