Go言語備忘録

# Goの勉強ver.0
昔プロゲートで好きになったGOを本格的に勉強するための備忘録
- go.mod入れようねって話。最初に躓きました
- go.sumで外部ライブラリ
```go:go.mod
module パッケージ名

go 1.23.1
```

- 変数の代入 
```golang
func main(){
    a:="主要な記事："
    s:="Qiita"
    q:="Zenn"
    b:="と"
    z:=a+s+b+z
    fmt.Println(z)
    }
```
- コンテキストとcli
```golang:gotest.go
package main

import (
	"fmt"
	"os"
	"strconv"

	"github.com/urfave/cli"
)

func cliinit() {
	app := cli.NewApp()

	app.Action = func(content *cli.Context) error {

		var naming [100]string
		for i := 0; i < 100; i++ {
			var strc string = strconv.Itoa(i)
			naming[i] = "人生" + strc
			app.Name = naming[i]
			app.Usage = naming[i]
			fmt.Println(content.Args().Get(i))
		}
		return nil
	}
	app.Flags = []cli.Flag{
		cli.BoolFlag{
			Name:  "cat, dog",
			Usage: "Echo with animal",
		},
	}

	app.Version = "0.1"
	app.Run(os.Args)
}
```
- IPの取得とTCPの取得。osの使い方がまだよくわかってない
- 出来ればヘルプコマンドでコマンド一覧を出力したい
- check関数をまとめてエラー入力させたい
[参考元](https://qiita.com/yamad07/items/0d45c4ad4b025b8c3eb5)
```golang
package main

import (
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"strings"
)

func network() {
	var jajge []string = []string{
		"help",
		"?",
		"q",
		"question",
		"explain",
		"retry",
	}

	for _, ja_word := range jajge {
		if strings.Join(os.Args, " ") != ja_word {
			fmt.Println("No help command support, if you want to watch helpeer text,it command is %s", ja_word)
		} else if strings.Join(os.Args, " ") == ja_word {
			fmt.Printf("it port: %s", os.Args[0])
			ser := os.Args[1]
			tcp_info, err := net.ResolveTCPAddr("tcp4", ser)
			check(err)
			conn, err := net.DialTCP("tcp", nil, tcp_info)
			check(err)
			_, err = conn.Write([]byte("HEAD /HTTP/1.0\r\n\r\n"))
			check(err)
			//ReadAllが使えない。Goのversionが原因
			res, err := ioutil.ReadAll(conn)
			check(err)
			fmt.Println(string(res))
			os.Exit(1)
		}
	}

}

func check(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "Fatal error: %s", ere.Error())
		os.Exit(1)
	}
}
```
 - osの勉強。os.WriteFile使った方がいい。Create何であるの？
 ```golang
 package main

import (
	"fmt"
	"io"
	"os"
)

func main() {
	fi := "error"
	fmt.Println(fi)
	d := "os.csv"
	con, err := os.Create(d)
	if err != nil {
	}
	txt, err2 := os.Open(con.Name())
	if err2 != nil {
	}
	fmt.Println(txt)
	hang, err3 := io.Copy(os.Stderr, txt)
	if err3 != nil {
	}
	fmt.Println(hang)
	data := []byte("data:filecotrolbynaem")
	err4 := os.WriteFile(d, data, 0644)
	if err4 != nil {
	}
	dat, err5 := os.ReadFile(d)
	if err5 != nil {
	}
	fmt.Println(dat)
}

```
- 暗号周りのテスト。shaの名前ちょくちょく変わる
- type 名前 interfaceの使い方理解した方が分かりやすいかも
```golang
package main

import (
	"crypto"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"os"
)

func cryptotest(word string) {
	sha256 := crypto.SHA256
	b512 := crypto.BLAKE2b_512
	var thash crypto.Hash
	sh := sha1.Sum([]byte(word))
	fmt.Println(sh)
	bcry := []byte("test")
	enco := base64.NewEncoder(base64.StdEncoding, os.Stdout)
	deco := base64.NewDecoder(base64.StdEncoding, os.Stdout)

	fmt.Println(enco.Write(bcry))
	fmt.Println(deco.Read(bcry))
	fmt.Println(sha256.HashFunc())
	fmt.Println(thash.HashFunc())
	fmt.Println(sha256, word)
	fmt.Println(b512)

}
```
- JSONを扱ってみた。試作なので中身は適当
- map構造をjsonに変換する。jsonメソッド使えば簡単に出来そう
```golang:jsonio.go
package main

import (
	"fmt"
	"os"
	"strings"
)

func jsonio() {
	jsonelement := []string{"id", "name", "category", "amount", "money"}
	stt := make(map[string]person)
	for k, v := range jsonelement {
		if k-1 == 0 {
			stt[v] = person{name: v}
		} else if k-2 == 0 {
			stt[v] = person{category: v}
		} else {
			stt[v] = person{id: k}
		}
		stt[v] = person{amount: k}
		stt[v] = person{money: k}
	}
	fmt.Println(stt)
	bdata := []byte(strings.Join(jsonelement, " "))
	err := os.WriteFile("sample.json", bdata, 0644)
	if err != nil {
	}
}

type person struct {
	id       int
	name     string
	category string
	amount   int
	money    int
}
```
- JSONをファイルで出力
- 文字列はいけるがjsonメソッドでバイト列変換すると何も出力されない
- fmtすると数値は表示される。暗号化されてる？
```golang
package main

import (
	"encoding/json"
	"fmt"
	"os"
)

type data struct {
	id    int
	name  string
	age   int
	score int
	speed float64
}

func jio() {
	var people = data{
		id:    0,
		name:  "お馬鹿さん",
		age:   12,
		score: 1200,
		speed: 0.2345,
	}
	fmt.Println(people)
	jsooon, err := json.Marshal(people)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(jsooon)
	err = os.WriteFile("txt.json", jsooon, 0644)
	if err != nil {
		fmt.Println(err)
	}
	err = os.WriteFile("tdet.json", []byte(people.name), 0644)
	if err != nil {
		fmt.Println(err)
	}
}
```
- netの扱い練習。IPの型を探すのに苦労した
- Pasrse文でIPとHOST，CIDERは変換できる
- 大体長い関数名やInterfaceは構造体が多い。短いのから覚えてくとよさげ
- その他は文字列同様Contain文やEqualが使える
```golang:netiphost.go
package main

import (
	"fmt"
	"log"
	"net"
	"net/http"
	"time"
)

// ネットワークプログラム。
// 各層毎にクラス分け
func client() {
	service := ":7777"

	tcpAddr, err := net.ResolveTCPAddr("tcp", service)
	if err != nil {
		panic(err)
	}
	listener, err := net.ListenTCP("tcp", tcpAddr)
	if err != nil {
	}
	for {
		conn, err := listener.Accept()
		if err != nil {
			continue
		}
		dtime := time.Now().String()
		conn.Write([]byte(dtime))
		conn.Close()
	}
}

func server(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "hello world")
}

func handle() {
	http.HandleFunc("/", server)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}

func netrip() {
	packet, err := net.ListenPacket("udp", ":9090")
	if err != nil {
		return
	}
	fmt.Println(packet)

	ip := net.ParseIP("210.123.100.1")
	d := net.TCPAddr{
		IP:   ip,
		Port: 5656,
		Zone: "",
	}
	fmt.Println(d.IP, d.Port, d.Zone)
	if ip.IsLinkLocalMulticast() {
		fmt.Println("LinkLocalMulticast")
	} else if ip.IsLinkLocalUnicast() {
		fmt.Println("LinkLocalUnicast")
	} else if ip.IsGlobalUnicast() {
		fmt.Println("GlobalUnicast")
	} else if ip.IsMulticast() {
		fmt.Println("Multicast")
	} else if ip.IsLoopback() {
		fmt.Println("Loopback")
	} else if ip.IsPrivate() {
		fmt.Println("Private")
	}
	hostip, err := net.LookupIP("ドメイン.com")
	if err != nil {
	}
	fmt.Println(hostip)
	cidr, i, err := net.ParseCIDR("192.168.1.0/24")
	if err != nil {
		return
	}
	fmt.Println(cidr)
	fmt.Println(i.String())
	ip1 := net.ParseIP("192.168.1.1")
	ip2 := net.ParseIP("192.168.1.1")
	if ip1.Equal(ip2) {
		fmt.Println("same ip")
	} else {
		fmt.Println("different ip")
	}

}
```