#23. ほぼ0から始めるA Tour of Go

# はじめに
こんにちはnayaaaaです。
私は現在インフラエンジニアをやっているのですが、今後開発言語を触れる可能性がでてきたので、最近は少しずつGo言語の学習を進めており、`A Tour of Go`に取り組んでいます。

https://go-tour-jp.appspot.com/list


# なぜGo?
実はRubyを勉強するかGoを勉強するかで悩んだのですが、
Goを選んだ理由は、以前、ChatGPTでGoを用いてMySQLのdumpのスクリプトを作成した際に、
少しGoの勉強をしたことがあったという理由とGoの本を読んだことがある（少し読んだだけで実際にはあまり触れていなかった）というところになります。

他にも、私がKubernetesを勉強しており、Kubernetesの勉強をしているならGoを覚えることでより深く理解することができる（KubernetesはGo言語でできてる）と思ったためです。

https://www.amazon.co.jp/%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0Go%E8%A8%80%E8%AA%9E-CodeZine-BOOKS-%E6%9D%BE%E5%B0%BE-%E6%84%9B%E8%B3%80/dp/4798142417

以前ChatGPTに作らせたもの↓（もろAIに作らせてる感が出てますね）


```
package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"time"
)

func main() {
	// 環境変数を設定するためのスクリプトを実行
	cmd := exec.Command("/bin/sh", "/tmp/set_db.env.sh")
	err := cmd.Run()
	if err != nil {
		log.Fatalf("Error running set_db.env.sh: %v", err)
	}

	// 設定
	dbName := "wordpress_db"
	date := time.Now().Format("2006-01-02")
	daysToKeep := 5

	// バックアップディレクトリの作成
	backupDir := filepath.Join(os.Getenv("HOME"), "backup", time.Now().Format("20060102"))
	err = os.MkdirAll(backupDir, 0755)
	if err != nil {
		log.Fatalf("Error creating backup directory: %v", err)
	}

	// バックアップファイルパス
	backupFile := filepath.Join(backupDir, fmt.Sprintf("%s-%s.sql", dbName, date))

	// 古いバックアップファイルの削除対象を設定
	oldDate := time.Now().AddDate(0, 0, -daysToKeep).Format("20060102")
	oldDump := filepath.Join(backupDir, fmt.Sprintf("mysqldump.%s.sql", oldDate))

	// mysqldump コマンドの実行
	dbUser := os.Getenv("DB_USER")
	dbPassword := os.Getenv("DB_PASSWORD")

	dumpCmd := exec.Command("mysqldump", "-v", "--single-transaction", "--skip-lock-tables", "--default-character-set=utf8mb4", "-h", "localhost", "-u", dbUser, fmt.Sprintf("-p%s", dbPassword), dbName)
	gzipCmd := exec.Command("gzip")

	// パイプで mysqldump の出力を gzip に渡す
	dumpOut, err := dumpCmd.StdoutPipe()
	if err != nil {
		log.Fatalf("Error getting stdout pipe: %v", err)
	}

	gzipIn, err := gzipCmd.StdinPipe()
	if err != nil {
		log.Fatalf("Error getting stdin pipe for gzip: %v", err)
	}

	// gzip の出力をファイルに書き込む
	backupFileHandle, err := os.Create(filepath.Join(backupDir, fmt.Sprintf("bk.%s.gz", time.Now().Format("20060102"))))
	if err != nil {
		log.Fatalf("Error creating backup file: %v", err)
	}
	defer backupFileHandle.Close()

	gzipCmd.Stdout = backupFileHandle

	// mysqldump と gzip を同時に実行
	err = dumpCmd.Start()
	if err != nil {
		log.Fatalf("Error starting mysqldump: %v", err)
	}
	err = gzipCmd.Start()
	if err != nil {
		log.Fatalf("Error starting gzip: %v", err)
	}

	// パイプのデータを流す
	go func() {
		_, err = io.Copy(gzipIn, dumpOut)
		if err != nil {
			log.Fatalf("Error piping mysqldump to gzip: %v", err)
		}
		gzipIn.Close()
	}()

	// コマンド完了を待機
	err = dumpCmd.Wait()
	if err != nil {
		log.Fatalf("mysqldump failed: %v", err)
	}
	err = gzipCmd.Wait()
	if err != nil {
		log.Fatalf("gzip failed: %v", err)
	}

	// 古いバックアップの削除
	err = os.Remove(oldDump)
	if err != nil && !os.IsNotExist(err) {
		log.Fatalf("Error deleting old dump: %v", err)
	}

	// バックアップ完了のメッセージ
	fmt.Printf("Backup of %s completed and old backups deleted.\n", dbName)
}

```




# とりあえず目標として

- A Tour of Goの内容を一通り理解できるようにする
- 基本構文を覚える（人のコードを見ても理解できるようになりたい）
- 何か形として成果物を作ってみる（簡単なCLIツールなどを作れるようにする）

上記を目標として気長にやっていきたいと思います。


# まとめ
あまり、開発言語の経験があまりなかったため、なかなか苦戦していますが、
とりあえず、最終的には何か形として成果物を作れるようになるところまでにはなりたいですね。

今後の私のキャリアパス的にはあくまでも主軸はインフラというところではあるのですが、
インフラエンジニアでもコードを書けることが必要という風潮になってきているので、
これからも開発言語は気長に勉強を続けていきたいと思います。
以上となります。ありがとうございます。