Go言語チュートリアル

目次

1. はじめに

Go言語(または Golang)は、Googleによって開発されたオープンソースのプログラミング言語です。シンプルで効率的、そして並行処理に強いという特徴があります。

2. インストール

Go言語の公式サイト(https://golang.org)からインストーラーをダウンロードし、指示に従ってインストールしてください。

3. Hello, World!

まずは、定番の "Hello, World!" プログラムを作成しましょう。

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

このコードを hello.go として保存し、ターミナルで以下のコマンドを実行します:

go run hello.go

4. 変数と定数

Go言語での変数宣言と定数定義の方法を学びましょう。

var x int = 10
y := 20 // 型推論による短縮形

const Pi = 3.14159

5. データ型

Go言語の基本的なデータ型には以下があります:

6. 制御構造

Go言語の制御構造には、if文、for文、switch文などがあります。

// if文
if x > 0 {
    fmt.Println("Positive")
} else if x < 0 {
    fmt.Println("Negative")
} else {
    fmt.Println("Zero")
}

// for文
for i := 0; i < 5; i++ {
    fmt.Println(i)
}

// switch文
switch day {
case "Monday":
    fmt.Println("It's Monday")
case "Tuesday":
    fmt.Println("It's Tuesday")
default:
    fmt.Println("It's another day")
}

7. 関数

Go言語での関数定義と使用方法を見てみましょう。

func add(x int, y int) int {
    return x + y
}

func main() {
    result := add(5, 3)
    fmt.Println("5 + 3 =", result)
}

8. パッケージ

Go言語ではパッケージを使ってコードを整理します。

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println("The square root of 16 is", math.Sqrt(16))
}

9. 配列とスライス

Go言語では、配列は固定長、スライスは可変長のデータ構造です。

配列

// 配列の宣言と初期化
var a [5]int
b := [3]int{1, 2, 3}

// 配列の要素にアクセス
fmt.Println(b[1]) // 出力: 2

スライス

// スライスの宣言と初期化
s := []int{1, 2, 3, 4, 5}

// スライスの追加
s = append(s, 6)

// スライスの一部を取り出す
fmt.Println(s[1:4]) // 出力: [2 3 4]

10. マップ

マップはキーと値のペアを格納するデータ構造です。

// マップの宣言と初期化
m := make(map[string]int)

// 要素の追加
m["apple"] = 1
m["banana"] = 2

// 要素の取得
value, exists := m["apple"]
if exists {
    fmt.Println(value) // 出力: 1
}

// 要素の削除
delete(m, "banana")

// マップの反復処理
for key, value := range m {
    fmt.Printf("%s: %d\n", key, value)
}

// マップのサイズ
fmt.Println(len(m))

11. エラーハンドリング

Go言語では、エラーは値として扱われます。多くの関数は、最後の戻り値としてエラーを返します。

f, err := os.Open("filename.txt")
if err != nil {
    log.Fatal(err)
}
defer f.Close()

// カスタムエラーの作成
type MyError struct {
    message string
}

func (e *MyError) Error() string {
    return e.message
}

func doSomething() error {
    return &MyError{"something went wrong"}
}

12. ファイルの入出力

Go言語では、osパッケージとio/ioutilパッケージを使用してファイルの読み書きを行います。

ファイルの読み込み

import (
    "fmt"
    "io/ioutil"
)

func readFile() {
    content, err := ioutil.ReadFile("file.txt")
    if err != nil {
        fmt.Println("Error reading file:", err)
        return
    }
    fmt.Println(string(content))
}

ファイルの書き込み

import (
    "fmt"
    "io/ioutil"
)

func writeFile() {
    content := []byte("Hello, Go!")
    err := ioutil.WriteFile("output.txt", content, 0644)
    if err != nil {
        fmt.Println("Error writing file:", err)
        return
    }
    fmt.Println("File written successfully")
}

13. 並行処理

Go言語の強みの一つである並行処理について学びましょう。

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
}

この例では、goキーワードを使用してゴルーチン(軽量スレッド)を起動しています。

14. チャネルの使い方

チャネルは、ゴルーチン間でデータを送受信するための通信機構です。

// チャネルの作成
ch := make(chan int)

// データの送信
go func() {
    ch <- 42
}()

// データの受信
value := <-ch
fmt.Println(value) // 出力: 42

// バッファ付きチャネル
bufCh := make(chan int, 2)
bufCh <- 1
bufCh <- 2
// bufCh <- 3 // これはブロックする(バッファが満杯)

// チャネルのクローズ
close(ch)

// rangeを使用したチャネルの読み取り
for v := range ch {
    fmt.Println(v)
}

15. net/httpでのAPI作成

Go言語の標準ライブラリnet/httpを使用してシンプルなAPIを作成できます。

package main

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

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func main() {
    http.HandleFunc("/api/person", handlePerson)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func handlePerson(w http.ResponseWriter, r *http.Request) {
    person := Person{Name: "John Doe", Age: 30}
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(person)
}

16. go.modファイル

go.modファイルは、プロジェクトの依存関係を管理するために使用されます。

// go.modファイルの作成
go mod init example.com/myproject

// go.modファイルの例
module example.com/myproject

go 1.16

require (
    github.com/gin-gonic/gin v1.7.2
    github.com/go-sql-driver/mysql v1.6.0
)

// 依存関係の追加
go get github.com/some/dependency

// 依存関係の更新
go get -u