go修行16日目 time関数など



## time関数

- RFC3339がよく使われる Postgresqlなどで

```golang

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Now()
	fmt.Println(t)
	fmt.Println(t.Format(time.RFC3339))
	fmt.Println(t.Year(), t.Month(), t.Day(),
		t.Hour(), t.Minute(), t.Second())
}
```

```
2020-07-05 13:33:12.5673789 +0900 JST m=+0.002000201
2020-07-05T13:33:12+09:00
2020 July 5 13 33 12
```

## 正規表現

- WebサーバのバックエンドでURLによって処理を判定する場合などに使う

```golang

package main

import (
	"fmt"
	"regexp"
)

func main() {
	// プログラム内で1回だけとかならまとめて書く
	// aaaeなどがヒットする
	match, _ := regexp.MatchString("a([a-z]+)e", "apple")
	fmt.Println(match)

	// 何度も使いまわす場合、MustCompileで正規表現のみ宣言しておく
	r := regexp.MustCompile("a([a-z]+)e")
	ms := r.MatchString("apple")
	fmt.Println(ms)

	// s := "/view/test" というようなURLをひっかけたい
	r2 := regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
	fs := r2.FindString("/view/test")
	fmt.Println(fs)
	// 一部の文字だけ取り出したい場合
	fss := r2.FindStringSubmatch("/view/test")
	fmt.Println(fss, fss[0], fss[1], fss[2])
}
```


```
true
true
/view/test
[/view/test view test] /view/test view test
```

## sort

```golang

package main

import (
	"fmt"
	"sort"
)

func main() {
	i := []int{5, 3, 2, 8, 7}
	s := []string{"d", "a", "f"}
	p := []struct {
		Name string
		Age  int
	}{
		{"Nancy", 20},
		{"Vera", 30},
		{"Mike", 40},
		{"Bob", 50},
	}
	fmt.Println(i, s, p)
	sort.Ints(i)
	sort.Strings(s)
	// 名前順
	sort.Slice(p, func(i, j int) bool { return p[i].Name < p[j].Name })
	// 年齢順
	sort.Slice(p, func(i, j int) bool { return p[i].Age < p[j].Age })
	fmt.Println(i, s, p)
}
```

## iota

```golang

package main

import "fmt"

// 自動的に連番を振ってくれる iotaを入れてあげなくても自動的にインクリメントされる
const (
	c1 = iota
	c2
	c3
)

const (
	// 0を使わない場合「_」
	_      = iota
	KB int = 1 << (10 * iota)
	MB
	GB
)

func main() {
	fmt.Println(c1, c2, c3)
	fmt.Println(KB, MB, GB)
}
```

```
0 1 2
1024 1048576 1073741824
```

## context
- Webアプリなどでユーザーリクエストの処理が長い場合のタイムアウト設定などに使う

```golang
package main

import (
	"context"
	"fmt"
	"time"
)

func longProcess(ctx context.Context, ch chan string) {
	fmt.Println("run")
	// 2秒
	time.Sleep(2 * time.Second)
	fmt.Println("finish")
	ch <- "result"
}

func main() {
	ch := make(chan string)
	// context timeoutを付け加えられる
	ctx := context.Background()
	// 1秒
	ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
	defer cancel()
	go longProcess(ctx, ch)

	for {
		select {
		case <-ctx.Done():
			fmt.Println(ctx.Err())
			return
		case <-ch:
			fmt.Println("success")
			return
		}
	}
}
```

```
run
context deadline exceededg
```

## ioutil

```golang
package main

import (
	"fmt"
	"io/ioutil"
	"log"
)

func main() {
	// パケットやファイルを読み込む場合ioutilを使う
	// osとは役割が違う
	content, err := ioutil.ReadFile("main.go")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(content))

	if err := ioutil.WriteFile("ioutil_temp.go", content, 0666); err != nil {
		log.Fatalln(err)
	}
}

```

```
API server listening at: 127.0.0.1:17064
package main

import (
	"fmt"
	"io/ioutil"
	"log"
)

func main() {
	// パケットやファイルを読み込む場合ioutilを使う
	// osとは役割が違う
	content, err := ioutil.ReadFile("main.go")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(content))

	if err := ioutil.WriteFile("ioutil_temp.go", content, 0666); err != nil {
		log.Fatalln(err)
	}
}
Process exiting with code: 0
```

ファイルが生成される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/def4eeba-d654-d9e6-4445-a0dc66d6fdd2.png)

```golang

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
)

func main() {
	r := bytes.NewBuffer([]byte("abc"))
	// バッファはReadAllで読み込む
	content, _ := ioutil.ReadAll(r)
	fmt.Println(string(content))
}

```

```
abc
```

## ネットワーク系パッケージ

- URLを読み込む

```golang

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	resp, _ := http.Get("http://example.com")
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
}
```

```
API server listening at: 127.0.0.1:37622
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
Process exiting with code: 0
```

```golang
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

func main() {
	// URLが正しいものかチェック
	base, _ := url.Parse("http://example.com")
	// example.comのあとのURLをつけることができる
	reference, _ := url.Parse("/test?a=1&n=2")
	endpoint := base.ResolveReference(reference).String()
	fmt.Println(endpoint)
	req, _ := http.NewRequest("GET", endpoint, nil)
	// ヘッダをつけることができる
	req.Header.Add("If-None-Match", "W/xxxx")
	q := req.URL.Query()
	q.Add("c", "3&%")
	fmt.Println(q)
	fmt.Println(q.Encode())
	req.URL.RawQuery = q.Encode()

	var client *http.Client = &http.Client{}
	resp, _ := client.Do(req)
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
}
```

```
API server listening at: 127.0.0.1:36071
http://example.com/test?a=1&n=2
map[a:[1] c:[3&%] n:[2]]
a=1&c=3%26%25&n=2
<!doctype html>
<html>
<head>
```

## unmarhal

- jsonデータをネットワークから受け取る場合などに利用

```golang
package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	// ``で囲ってあげると変換してくれる
	Name      string   `json:"name"`
	Age       int      `json:"age"`
	NickNames []string `json:"nicknames"`
}

func main() {
	b := []byte(`{"name":"mike","age":20,"nicknames":["a","b","c"]}`)
	var p Person
	// ネットワークから入ってきたjsonをStructに自動的に入れてくれる
	if err := json.Unmarshal(b, &p); err != nil {
		fmt.Println(err)
	}
	fmt.Println(p.Name, p.Age, p.NickNames)

	// 再度変換をかける
	v, _ := json.Marshal(p)
	fmt.Println(string(v))
}
```

```
mike 20 [a b c]
{"name":"mike","age":20,"nicknames":["a","b","c"]}
```