Go入門30日間で学ぶべきこと:goroutine・defer・エラーハンドリング・net/http
概要¶
Go を始めて 30 日間で学ぶべき最重要概念を厳選したリスト。「Go の並行処理が本質なので Day 1 から goroutine を学べ」という実践的なアドバイス。
詳細¶
1. goroutine + channel(並行処理)¶
Go の最大の強みであり、最初に学ぶべき概念。
// goroutine: go キーワードで並行実行
func fetchData(url string, ch chan<- string) {
resp, _ := http.Get(url)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
ch <- string(body)
}
func main() {
ch := make(chan string, 2)
go fetchData("https://api1.example.com", ch) // 並行実行
go fetchData("https://api2.example.com", ch)
result1 := <-ch // チャネルから受信(ブロック)
result2 := <-ch
fmt.Println(result1, result2)
}
2. defer(クリーンアップの制御)¶
関数の終了時に必ず実行される。パニック時にも動作する。
func readFile(path string) ([]byte, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close() // ← 関数が終わる時に必ず閉じる(エラーでも同様)
return io.ReadAll(f)
}
3. エラーハンドリング¶
Go は例外を throw しない。エラーは戻り値として明示的に扱う。
// Go のスタイル: エラーを値として返す
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
// 呼び出し側は必ずエラーをチェックする
result, err := divide(10, 0)
if err != nil {
log.Printf("error: %v", err)
return
}
// エラーを無視すると lint で警告(errcheck)
4. net/http(HTTP サーバー)¶
標準ライブラリだけで本番 HTTP サーバーが作れる。
package main
import (
"encoding/json"
"net/http"
)
func main() {
mux := http.NewServeMux()
// Go 1.22+: メソッドとパスパターンをサポート
mux.HandleFunc("GET /users/{id}", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"id": id})
})
http.ListenAndServe(":8080", mux)
}
5. その他の重要ポイント¶
// interface: 暗黙的な実装(implements キーワード不要)
type Writer interface {
Write(p []byte) (n int, err error)
}
// struct embedding: 継承に近い合成
type Logger struct {
*log.Logger
prefix string
}
// context: タイムアウトとキャンセルの伝播
func doWork(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
case result := <-doHeavyWork():
return nil
}
}
なぜ重要か / いつ使うか¶
- Go を初めて学ぶときの学習優先度の整理
- 「Go で何から学べばいいか」と聞かれた後輩への回答
- 他言語からの移行時に「Go らしい書き方」を掴むとき