Go 基礎

# はじめに
業務でgoを用いて開発をおこなった際に、基礎的な文法等について不明であった点について自身の頭の中を整理するために記事にまとめました。
メモ書きのような形式で記事にしているので、網羅性に欠ける部分が存在する点についてはご了承ください。

# 基礎文法

*  _(アンダーバー)は、アンダースコア変数と呼び、宣言はするが後で使用しない変数を意味する。

* アンダースコア変数を使用してスライスの中身を取り出す。
```go
for _, value := range values {
    fmt.Println(value)
}
```
* スライスからkeyとvalueを取り出す。

```go
for key, value := range values {
    fmt.Println(key)
    fmt.Println(value)
}
```

## slice
```go
var list1 []string
var list2 []int
var list3 []byte

list4 := []string{"test1", "test2"}
fmt.Println(list4) // [test1 test2]
```

https://qiita.com/k-penguin-sato/items/daad9986d6c42bdcde90#slices%E3%82%B9%E3%83%A9%E3%82%A4%E3%82%B9

### sliceに要素を追加する
* 基本
```go
newSlice = append(slice, 追加要素)
```

* 応用
```go
	var keys []*genproto.Archive
	for _, v := range archives {
		operatorcomaster, _ := v.QueryOrganization().Only(ctx)
		po := toProtoArchive(v, operatorcomaster)
		keys = append(keys, po)
	}
```

# slice及びmapを取得するループ処理
## slice
```go
var slice = []string{"Golang", "Ruby", "Javascript", "Python"}

func main() {
    for index, value := range slice {
        fmt.Println(index, value)
        //=> 0 Golang
        //=> 1 Ruby
        //=> 2 Javascript
        //=> 3 Python
    }
}
```

## map
```go
var mapping = map[string]int{
    "one":   1,
    "two":   2,
    "three": 3,
    "four":  4,
    "five":  5,
}

func main() {
    for key, value := range mapping {
        fmt.Println(key, value)
        //=> four 4
        //=> five 5
        //=> one 1
        //=> two 2
        //=> three 3
    }
}
```

https://qiita.com/k-penguin-sato/items/a320072fa09502bde3e9#range-for-%E3%81%AE-range%E7%AF%80

# レシーバ
関数外で定義した構造体などをレシーバを通して受け取り、関数内で使用することができる。
値レシーバとポインタレシーバが存在する。

```go
type Greet struct {
	greet string
}

func (s Greet) translate() {   // 変数レシーバ
	s.greet = "hello"
}

func (s *Greet) translate2() { // ポインタレシーバ
	s.greet = "hello"
}

func main() {
	str := Greet{"こんにちは"}

	str.translate()
	fmt.Println(str.greet) // こんにちは
	str.translate2()
	fmt.Println(str.greet) // hello
}
```

# ポインタ
https://qiita.com/Sekky0905/items/447efa04a95e3fec217f
## apiのuriからリクエストパラメータを取得する
```go
var param string = r.FormValue("param1")
```

# datetimeについて

```go
	fileName := "operator_list." + time.Now().Format("20060102") + ".csv"
```
https://qiita.com/ruiu/items/5936b4c3bd6eb487c182

## webサーバーを立ち上げる

* main.goファイルの中で `main` 関数が一番最初に実行される
* `go run main.go` でmain.goがコンパイルされたうえで実行され、api用のwebサーバーが立ち上がる。

```go:main.go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

func main() {
	StartWebServer()
}

func StartWebServer() {
	fmt.Println("Start Web Server")
	http.HandleFunc("/getUser", getUser)
	http.ListenAndServe(fmt.Sprintf(":%d", 60000), nil)
	return
}

func getUser(w http.ResponseWriter, r *http.Request) {

	var user_name string = "taro"

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(user_name)
}
```

# go mod

## go moduleの初期化

```terminal
go mod init <project-name>

### 公開前提の場合はモジュールのパスを指定する
$ go mod init github.com/nishina555/go-example
```

## 指定したパッケージのinstall
個別にパッケージをインストールする場合
```terminal
go get [パッケージ名]
```

## 依存モジュールを一括ダウンロードする
```terminal
go mod tidy
```

## バイナリ形式の実行ファイルを$GOPATH/bin以下にインストールする
```terminal
go install
```
https://zenn.dev/optimisuke/articles/105feac3f8e726830f8c

# ドット3つ
指定したディレクトリ以下の全てのファイルを意味する。

```terminal
go generate ./...
```

https://ja.stackoverflow.com/questions/40796/go-get%E3%81%AEurl-%E3%81%A8%E3%81%84%E3%81%86%E3%83%88%E3%83%AA%E3%83%97%E3%83%AB%E3%83%89%E3%83%83%E3%83%88%E3%81%AF%E3%81%A9%E3%81%86%E3%81%84%E3%81%86%E6%84%8F%E5%91%B3%E3%81%A7%E3%81%99%E3%81%8B