Slide 1

Slide 1 text

Go言語総合ガイド 初学者のための学習資料 1

Slide 2

Slide 2 text

1. Go言語の概要と設計哲学 2

Slide 3

Slide 3 text

Go言語の特徴 Google社が開発した静的型付け言語 ▶ 2009年に公開され、システムプログラミングのために設計 ▶ C言語の簡潔さとPythonの読みやすさを兼ね備える ▶ 並行処理と高速な実行速度が特徴 ▶ ガベージコレクション機能により、メモリ管理を自動化 ▶ 3

Slide 4

Slide 4 text

設計哲学:シンプルさと明確さの追求 最小限の言語機能:学習曲線を緩やかにし、生産性を向上 ▶ 明示的な型システム:コードの意図を明確に表現 ▶ エラー処理の簡素化:try-catchの代わりに、エラーを戻り値として扱う ▶ 継承の代わりにコンポジションを推奨:柔軟で理解しやすいコード構造を実現 ▶ 4

Slide 5

Slide 5 text

主な用途 Webサーバー開発:高性能で軽量なHTTPサーバーの構築が可能 ▶ ネットワークプログラミング:並行処理機能を活かした効率的な通信処理 ▶ システムプログラミング:低レベルの制御と高レベルの抽象化を両立 ▶ クラウドインフラストラクチャ:Dockerやクーベネテスなどの重要なツールがGoで開発 ▶ 5

Slide 6

Slide 6 text

用語辞書 静的型付け言語:プログラムのコンパイル時に変数の型が決定される言語 ▶ ガベージコレクション:プログラムが使用しなくなったメモリを自動的に解放する機能 ▶ 並行処理:複数の処理を同時に進行させること ▶ コンポジション:オブジェクト指向プログラミングにおいて、既存のオブジェクトを組み合わせて新しいオブジェクトを 作成する手法 ▶ 6

Slide 7

Slide 7 text

2. 開発環境のセットアップとツールチェーン 7

Slide 8

Slide 8 text

Go言語のインストール 公式サイト(golang.org)からインストーラーをダウンロード ▶ OSに応じたインストール手順に従う ▶ インストール後、環境変数GOPATHとGOROOTを適切に設定 ▶ コマンドラインで go version を実行し、インストールを確認 ▶ 8

Slide 9

Slide 9 text

統合開発環境(IDE)の選択 Visual Studio Code + Go拡張機能 ▶ 軽量で多機能、無料で利用可能 - インテリセンス、デバッグ機能、コード補完など豊富な機能 - GoLand(JetBrains製) ▶ Go専用のIDE、高度な機能と快適な開発環境 - 有料だが、学生や教育機関向けの無料ライセンスあり - 9

Slide 10

Slide 10 text

プロジェクト構成 GOPATHの理解と設定 ▶ Goのワークスペースを指定する環境変数 - 通常は $HOME/go に設定 - Go Modulesの基本 ▶ Go 1.11以降で導入された依存関係管理システム - go mod init でプロジェクトを初期化 - go.mod ファイルで依存関係を管理 - 10

Slide 11

Slide 11 text

統合ツールチェーン:go buildコマンド Goプログラムのコンパイルとビルドを行う ▶ 使用例: go build main.go ▶ クロスコンパイルも簡単に実行可能 ▶ 例: GOOS=linux GOARCH=amd64 go build main.go - 最適化されたバイナリを生成 ▶ 11

Slide 12

Slide 12 text

統合ツールチェーン:go testコマンド Goの標準テストフレームワークを使用したテスト実行 ▶ 使用例: go test ./... (すべてのパッケージをテスト) ▶ テストカバレッジの計測も可能: go test -cover ./... ▶ ベンチマークテストの実行: go test -bench=. ▶ 12

Slide 13

Slide 13 text

統合ツールチェーン:go fmtコマンド Goコードを標準的なスタイルにフォーマット ▶ 使用例: go fmt main.go ▶ プロジェクト全体に適用: go fmt ./... ▶ チーム開発での一貫性を保つのに役立つ ▶ 13

Slide 14

Slide 14 text

統合ツールチェーン:go generateコマンド ソースコード生成を自動化するツール ▶ コード内の特殊なコメントに基づいて動作 ▶ 例:プロトコルバッファのコード生成、モックオブジェクトの生成など ▶ 使用例: go generate ./... ▶ 14

Slide 15

Slide 15 text

用語辞書 GOPATH:Goのワークスペースを指定する環境変数 ▶ GOROOT:Goのインストールディレクトリを指定する環境変数 ▶ Go Modules:Goの依存関係管理システム ▶ クロスコンパイル:異なるOSやアーキテクチャ向けにプログラムをコンパイルすること ▶ ベンチマークテスト:プログラムの性能を測定するためのテスト ▶ 15

Slide 16

Slide 16 text

3. 基本文法と型システム 16

Slide 17

Slide 17 text

変数宣言 明示的な宣言: var name string = "Gopher" ▶ 型推論を使用した短縮構文: name := "Gopher" ▶ 複数変数の同時宣言: var x, y int = 10, 20 ▶ 定数宣言: const Pi = 3.14159 ▶ 17

Slide 18

Slide 18 text

ゼロ値の概念 変数宣言時に初期化しない場合、自動的にゼロ値が設定される ▶ 数値型:0 ▶ ブール型:false ▶ 文字列型:""(空文字列) ▶ ポインタ、インターフェース、スライス、マップ、チャネル:nil ▶ 18

Slide 19

Slide 19 text

基本データ型 整数型:int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64 ▶ 浮動小数点型:float32, float64 ▶ 複素数型:complex64, complex128 ▶ ブール型:bool ▶ 文字列型:string ▶ バイト型:byte(uint8の別名) ▶ ルーン型:rune(int32の別名、Unicodeコードポイントを表す) ▶ 19

Slide 20

Slide 20 text

複合データ型 type Person struct { Name string Age int } 配列:固定長の要素の集合。 var a [5]int ▶ スライス:可変長の配列のようなデータ構造。 s := []int{1, 2, 3} ▶ マップ:キーと値のペアを格納。 m := map[string]int{"apple": 1, "banana": 2} ▶ 構造体:異なる型のフィールドを集めたもの。 ▶ 20

Slide 21

Slide 21 text

制御構造:if文 if x > 0 { fmt.Println("Positive") } else if x < 0 { fmt.Println("Negative") } else { fmt.Println("Zero") } if err := doSomething(); err != nil { // エラー処理 } 基本的な使い方: ▶ 初期化付きif文: ▶ 21

Slide 22

Slide 22 text

制御構造:for文 for i := 0; i < 5; i++ { fmt.Println(i) } n := 0 for n < 5 { n++ } for { // 処理 } 基本的なfor文: ▶ while的な使い方: ▶ 無限ループ: ▶ 22

Slide 23

Slide 23 text

制御構造:switch文 switch day { case "Monday": fmt.Println("It's Monday") case "Tuesday": fmt.Println("It's Tuesday") default: fmt.Println("It's another day") } switch { case n < 0: fmt.Println("Negative") case n > 0: fmt.Println("Positive") default: fmt.Println("Zero") } 基本的な使い方: ▶ 式を使ったswitch: ▶ 23

Slide 24

Slide 24 text

defer文の使用法 f, err := os.Open("file.txt") if err != nil { return err } defer f.Close() // ファイル操作 関数の終了時に実行される処理を指定 ▶ リソースの解放やクリーンアップに便利 ▶ 例: ▶ 複数のdefer文がある場合、後入れ先出し(LIFO)で実行される ▶ 24

Slide 25

Slide 25 text

用語辞書 ゼロ値:変数が初期化されていない場合に自動的に設定される値 ▶ スライス:可変長の配列のようなデータ構造 ▶ マップ:キーと値のペアを格納するデータ構造 ▶ ルーン:Unicodeコードポイントを表すint32の別名 ▶ defer:関数の終了時に実行される処理を指定するキーワード ▶ 25

Slide 26

Slide 26 text

4. 関数とメソッド 26

Slide 27

Slide 27 text

関数の定義と呼び出し func add(x int, y int) int { return x + y } func divide(x, y float64) (float64, error) { if y == 0 { return 0, errors.New("division by zero") } return x / y, nil } func rectangle(width, height int) (area, perimeter int) { area = width * height perimeter = 2 * (width + height) return // 名前付き戻り値を使用する場合、空のreturnで良い } 基本的な関数定義: ▶ 複数の戻り値: ▶ 名前付き戻り値: ▶ 27

Slide 28

Slide 28 text

メソッドの定義 type Rectangle struct { Width, Height float64 } func (r Rectangle) Area() float64 { return r.Width * r.Height } func (r *Rectangle) Scale(factor float64) { r.Width *= factor r.Height *= factor } 構造体に対するメソッド: ▶ ポインタレシーバを使用したメソッド: ▶ 28

Slide 29

Slide 29 text

値レシーバと参照レシーバの違い 値レシーバ:メソッドが呼び出されたオブジェクトのコピーを操作 ▶ 参照レシーバ:メソッドが呼び出されたオブジェクト自体を操作 ▶ 使い分け: ▶ 値レシーバ:オブジェクトの状態を変更しない場合 - 参照レシーバ:オブジェクトの状態を変更する場合、または大きなオブジェクトのコピーを避けたい場合 - 29

Slide 30

Slide 30 text

関数型プログラミングの要素 var compute func(int, int) int compute = func(x, y int) int { return x + y } result := compute(3, 4) // 7 func applyOperation(x, y int, op func(int, int) int) int { return op(x, y) } sum := applyOperation(5, 3, func(a, b int) int { return a + b }) // 8 関数を変数として扱う: ▶ 高階関数(関数を引数や戻り値として扱う関数) : ▶ 30

Slide 31

Slide 31 text

無名関数とクロージャ func() { fmt.Println("Hello, World!") }() func adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum } } add := adder() fmt.Println(add(1)) // 1 fmt.Println(add(2)) // 3 無名関数: ▶ クロージャ(外部の変数を捕捉する関数) : ▶ 31

Slide 32

Slide 32 text

用語辞書 メソッド:特定の型(通常は構造体)に関連付けられた関数 ▶ レシーバ:メソッドが関連付けられる型のインスタンス ▶ 値レシーバ:メソッドがレシーバのコピーを操作する方式 ▶ 参照レシーバ:メソッドがレシーバ自体を操作する方式 ▶ クロージャ:外部の変数を捕捉する関数 ▶ 32

Slide 33

Slide 33 text

5. 構造体とインターフェース 33

Slide 34

Slide 34 text

構造体の定義と使用 type Person struct { Name string Age int } p1 := Person{"Alice", 30} p2 := Person{Name: "Bob", Age: 25} p3 := Person{Name: "Charlie"} // Ageは0(ゼロ値)で初期化される fmt.Println(p1.Name) // Alice p2.Age = 26 基本的な構造体の定義: ▶ 構造体の初期化: ▶ 構造体のフィールドへのアクセス: ▶ 34

Slide 35

Slide 35 text

構造体のメソッド func (p Person) Greet() string { return fmt.Sprintf("Hello, my name is %s and I'm %d years old", p.Name, p.Age) } p := Person{"Dave", 30} fmt.Println(p.Greet()) // "Hello, my name is Dave and I'm 30 years old" メソッドの定義: ▶ メソッドの使用: ▶ 35

Slide 36

Slide 36 text

オブジェクト指向プログラミングの簡略化 type Employee struct { Person```go JobTitle string } e := Employee{Person: Person{"Eve", 28}, JobTitle: "Engineer"} fmt.Println(e.Name) // Eve(Personのフィールドに直接アクセス可能) fmt.Println(e.Greet()) // PersonのGreetメソッドも使用可能 Goは継承を使わずにコンポジションを推奨 ▶ 埋め込みを使用した構造体の拡張: ▶ 36

Slide 37

Slide 37 text

インターフェースの概念 type Shapes interface { Area() float64 Perimeter() float64 } type Rectangle struct { Width, Height float64 } func (r Rectangle) Area() float64 { return r.Width * r.Height } func (r Rectangle) Perimeter() float64 { return 2 * (r.Width + r.Height) } // RectangleはShapesインターフェースを実装していることになる インターフェースの定義: ▶ インターフェースの実装(暗黙的) : ▶ 37

Slide 38

Slide 38 text

ダックタイピング type Quacker interface { Quack() } type Duck struct{} func (d Duck) Quack() { fmt.Println("Quack!") } type Person struct{} func (p Person) Quack() { fmt.Println("The person imitates a duck.") } func MakeItQuack(q Quacker) { q.Quack() } MakeItQuack(Duck{}) // 出力: Quack! MakeItQuack(Person{}) // 出力: The person imitates a duck. Goのインターフェースは暗黙的に実装される ▶ 構造体がインターフェースで定義されたメソッドをすべて持っていれば、そのインターフェースを実装していることにな る ▶ 例: ▶ 38

Slide 39

Slide 39 text

空インターフェース func PrintAnything(v interface{}) { fmt.Printf("Value: %v, Type: %T\n", v, v) } PrintAnything(42) // 出力: Value: 42, Type: int PrintAnything("Hello") // 出力: Value: Hello, Type: string PrintAnything(true) // 出力: Value: true, Type: bool interface{} は任意の型を表す ▶ 動的型付けが必要な場合に使用 ▶ 例: ▶ 39

Slide 40

Slide 40 text

用語辞書 構造体:異なる型のフィールドを集めたデータ構造 ▶ コンポジション:既存の型を新しい型に埋め込むことで機能を拡張する手法 ▶ インターフェース:メソッドのシグネチャの集合を定義する型 ▶ ダックタイピング:オブジェクトの型ではなく、そのメソッドによって型を決定する方式 ▶ 空インターフェース:任意の型を表すインターフェース ▶ 40

Slide 41

Slide 41 text

6. 並行処理と同期 41

Slide 42

Slide 42 text

Goroutineの基本 func sayHello() { fmt.Println("Hello, Gopher!") } func main() { go sayHello() time.Sleep(time.Second) // メインゴルーチンが終了しないよう少し待つ } Goroutineは軽量スレッド ▶ 関数の前に go キーワードを付けて起動 ▶ 例: ▶ 42

Slide 43

Slide 43 text

Goroutineの特徴 非常に軽量(数KBのスタックから開始) ▶ 必要に応じてスタックサイズが動的に調整される ▶ OSスレッドよりも高速に作成・切り替え可能 ▶ 数千〜数百万のGoroutineを同時に実行可能 ▶ 43

Slide 44

Slide 44 text

チャネルの基本 Goroutine間でデータを送受信するための通信路 ▶ チャネルの作成: ch := make(chan int) // int型のチャネル ▶ データの送信: ch <- 42 ▶ データの受信: value := <-ch ▶ 44

Slide 45

Slide 45 text

バッファ付きチャネル ch <- 1 ch <- 2 ch <- 3 // ch <- 4 // ここでブロック(バッファが満杯) 一定数のデータを保持できるチャネル ▶ 作成: ch := make(chan int, 3) // バッファサイズ3のint型チャネル ▶ バッファが埋まるまで送信はブロックされない ▶ バッファが空の場合、受信はブロックされる ▶ 例: ▶ 45

Slide 46

Slide 46 text

select文 select { case v1 := <-ch1: fmt.Println("Received from ch1:", v1) case v2 := <-ch2: fmt.Println("Received from ch2:", v2) case ch3 <- 42: fmt.Println("Sent to ch3") default: fmt.Println("No channel operations ready") } 複数のチャネル操作を待機 ▶ 準備ができた操作から実行 ▶ 例: ▶ 46

Slide 47

Slide 47 text

CSP(Communicating Sequential Processes)モデル Goの並行処理モデルの基礎 ▶ プロセス間の通信に基づく並行性の理論 ▶ "通信によって同期する" という考え方 ▶ チャネルを使った通信がこのモデルの実装 ▶ 47

Slide 48

Slide 48 text

デッドロック検出 func main() { ch := make(chan int) ch <- 1 // デッドロック:受信側がいないのでブロック fmt.Println(<-ch) } 実行結果: fatal error: all goroutines are asleep - deadlock! Goランタイムは自動的にデッドロックを検出 ▶ すべてのGoroutineがブロックされた状態で検出 ▶ 例: ▶ 48

Slide 49

Slide 49 text

用語辞書 Goroutine:Goの軽量スレッド ▶ チャネル:Goroutine間のデータ通信に使用される通信路 ▶ バッファ付きチャネル:一定数のデータを保持できるチャネル ▶ select文:複数のチャネル操作を待機するための制御構造 ▶ CSP:通信による同期を基本とする並行処理モデル ▶ デッドロック:複数のプロセスが互いに待ち合って処理が進まなくなる状態 ▶ 49

Slide 50

Slide 50 text

7. エラー処理とパニック 50

Slide 51

Slide 51 text

エラー処理の基本 func divide(a, b float64) (float64, error) { if b == 0 { return 0, errors.New("division by zero") } return a / b, nil } result, err := divide(10, 0) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Result:", result) } Goでは error 型を使用してエラーを表現 ▶ 関数は通常、最後の戻り値としてエラーを返す ▶ 例: ▶ 51

Slide 52

Slide 52 text

カスタムエラーの作成 type MyError struct { Code int Message string } func (e *MyError) Error() string { return fmt.Sprintf("エラーコード %d: %s", e.Code, e.Message) } errors.New 関数を使用: err := errors.New("カスタムエラーメッセージ") ▶ fmt.Errorf を使用(フォーマット付き) : err := fmt.Errorf("値%dは不正です", value) ▶ カスタムエラー型の定義: ▶ 52

Slide 53

Slide 53 text

エラーのラッピング(Go 1.13以降) originalErr := errors.New("原因エラー") wrappedErr := fmt.Errorf("追加コンテキスト: %w", originalErr) if errors.Is(wrappedErr, originalErr) { fmt.Println("originalErrが含まれています") } エラーに追加情報を付加して伝播 ▶ fmt.Errorf と %w 動詞を使用: ▶ ラップされたエラーの取り出し: ▶ 53

Slide 54

Slide 54 text

パニックとリカバリ func mayPanic() { panic("予期せぬエラー") } func main() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered from panic:", r) } }() mayPanic() fmt.Println("この行は実行されません") } パニック:プログラムの実行を中断し、スタックをアンワインド ▶ リカバリ:パニックから回復し、通常の実行を再開 ▶ 例: ▶ 54

Slide 55

Slide 55 text

パニックの適切な使用 パニックは予期せぬエラーや致命的な状況に使用 ▶ 通常のエラー処理には error を使用すべき ▶ 初期化時の致命的エラーなど、回復不可能な状況でのみ使用 ▶ 可能な限り panic ではなく error を返すことを推奨 ▶ 55

Slide 56

Slide 56 text

用語辞書 エラー:Goにおける標準的なエラー処理メカニズム ▶ カスタムエラー:ユーザー定義のエラー型 ▶ エラーラッピング:エラーに追加情報を付加する技術 ▶ パニック:プログラムの実行を中断する緊急事態 ▶ リカバリ:パニックから回復するメカニズム ▶ 56

Slide 57

Slide 57 text

8. パッケージ管理とモジュール性 57

Slide 58

Slide 58 text

パッケージの概念 package mypackage func MyFunction() { // 実装 } 関連する機能をグループ化するための仕組み ▶ 各 .go ファイルは package 宣言で始まる ▶ 同じディレクトリ内のファイルは同じパッケージに属する ▶ 例: ▶ 58

Slide 59

Slide 59 text

パッケージの可視性 package mypackage var ExportedVar = 42 // 公開 var unexportedVar = "hello" // 非公開 func ExportedFunc() {} // 公開 func unexportedFunc() {} // 非公開 大文字で始まる識別子:エクスポートされる(公開) ▶ 小文字で始まる識別子:パッケージ内部でのみ使用可能(非公開) ▶ 例: ▶ 59

Slide 60

Slide 60 text

Go Modulesの基本 Go 1.11以降の依存関係管理システム ▶ プロジェクトごとに異なるバージョンの依存関係を管理可能 ▶ 主要コマンド: ▶ go mod init : 新しいモジュールの初期化 - go get : 依存関係の追加・更新 - go mod tidy : 使用されていない依存関係の削除 - go.mod ファイル:モジュール定義と依存関係を記述 ▶ 60

Slide 61

Slide 61 text

Go Modulesの使用例 go mod init github.com/username/project go get github.com/some/dependency module github.com/username/project go 1.16 require ( github.com/some/dependency v1.2.3 ) 1. モジュールの初期化: 2. 依存関係の追加: 3. go.mod ファイルの例: 61

Slide 62

Slide 62 text

標準ライブラリの活用 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World!") }) http.ListenAndServe(":8080", nil) Goは豊富な標準ライブラリを提供 ▶ 主要な標準パッケージ: ▶ fmt : フォーマット済み I/O - io : 基本的な I/O インターフェース - os : OS機能へのインターフェース - net/http : HTTPクライアントとサーバー - encoding/json : JSON処理 - time : 時間と日付の操作 - 例:HTTPサーバー ▶ 62

Slide 63

Slide 63 text

クロスプラットフォームサポート GOOS=windows GOARCH=amd64 go build main.go GOOS=linux GOARCH=amd64 go build main.go GOOS=darwin GOARCH=amd64 go build main.go // +build windows package main import "fmt" func main() { fmt.Println("This is a Windows-specific code") } Goは複数のプラットフォームをネイティブにサポート ▶ 単一のコードベースから異なるOS用のバイナリを生成可能 ▶ クロスコンパイルの例: ▶ プラットフォーム固有のコードは条件付きコンパイルで制御可能: ▶ 63

Slide 64

Slide 64 text

用語辞書 パッケージ:関連する機能をグループ化するための仕組み ▶ エクスポート:パッケージ外部から参照可能な要素を定義すること ▶ Go Modules:Goの依存関係管理システム ▶ クロスコンパイル:異なるOSやアーキテクチャ向けにプログラムをコンパイルすること ▶ 条件付きコンパイル:特定の条件下でのみコードをコンパイルする技術 ▶ 64

Slide 65

Slide 65 text

9. テストとベンチマーク 65

Slide 66

Slide 66 text

テストの基本 // main.go func Add(a, b int) int { return a + b } // main_test.go package main import "testing" func TestAdd(t *testing.T) { result := Add(2, 3) if result != 5 { t.Errorf("Add(2, 3) = %d; want 5", result) } } テストファイルは _test.go で終わる名前を持つ ▶ テスト関数は Test で始まる ▶ testing パッケージを使用 ▶ 66

Slide 67

Slide 67 text

テーブル駆動テスト func TestAdd(t *testing.T) { tests := []struct { a, b, want int }{ {2, 3, 5}, {0, 0, 0},{-1, 1, 0}, } for _, tt := range tests { if got := Add(tt.a, tt.b); got != tt.want { t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want) } } } 複数のテストケースを効率的に記述 ▶ データ構造を使用してテストケースを定義 ▶ 67

Slide 68

Slide 68 text

ベンチマークテスト func BenchmarkAdd(b *testing.B) { for i := 0; i < b.N; i++ { Add(2, 3) } } 実行: go test -bench=. パフォーマンス測定のためのテスト ▶ Benchmark で始まる関数名 ▶ testing.B を使用 ▶ 68

Slide 69

Slide 69 text

カバレッジテスト go test -cover 詳細なカバレッジレポート: go test -coverprofile=coverage.out go tool cover -html=coverage.out コードカバレッジを測定 ▶ -cover フラグを使用 ▶ 69

Slide 70

Slide 70 text

モックとスタブ type DataStore interface { GetUser(id int) (string, error) } type MockDataStore struct{} func (m *MockDataStore) GetUser(id int) (string, error) { return "Mock User", nil } func TestUsingMock(t *testing.T) { mock := &MockDataStore{} // mockを使用してテスト } 外部依存をシミュレートするためのテクニック ▶ インターフェースを活用 ▶ 70

Slide 71

Slide 71 text

用語辞書 テストファイル: _test.go で終わる名前を持つGoのテストコードファイル ▶ テーブル駆動テスト:複数のテストケースをデータ構造で定義するテスト手法 ▶ ベンチマーク:プログラムの性能を測定するためのテスト ▶ カバレッジ:テストがコードのどの部分を実行したかを示す指標 ▶ モック:テスト用に作成された外部依存のシミュレーション ▶ 71

Slide 72

Slide 72 text

10. GoのWeb開発 72

Slide 73

Slide 73 text

標準HTTPサーバー package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:]) } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } net/http パッケージを使用 ▶ 基本的なHTTPサーバーの例: ▶ 73

Slide 74

Slide 74 text

ルーティング http.HandleFunc("/", homeHandler) http.HandleFunc("/about", aboutHandler) r := mux.NewRouter() r.HandleFunc("/users/{id:[0-9]+}", getUserHandler).Methods("GET") 基本的なルーティング: ▶ Gorillaムックス(サードパーティライブラリ)を使用した高度なルーティング: ▶ 74

Slide 75

Slide 75 text

ミドルウェア func loggingMiddleware(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { log.Printf("Received request: %s %s", r.Method, r.URL.Path) next.ServeHTTP(w, r) } } http.HandleFunc("/", loggingMiddleware(homeHandler)) HTTPハンドラーをラップして追加機能を提供 ▶ 75

Slide 76

Slide 76 text

テンプレートエンジン tmpl := template.Must(template.ParseFiles("layout.html")) tmpl.Execute(w, struct{ Name string }{"Alice"}) layout.html:

Hello, {{.Name}}!

html/template パッケージを使用 ▶ 動的HTMLの生成 ▶ 76

Slide 77

Slide 77 text

データベース接続 import ( "database/sql" _ "github.com/go-sql-driver/mysql" ) db, err := sql.Open("mysql", "user:password@/dbname") if err != nil { log.Fatal(err) } defer db.Close() rows, err := db.Query("SELECT * FROM users") // rows の処理 database/sql パッケージを使用 ▶ 様々なデータベースドライバーをサポート ▶ 77

Slide 78

Slide 78 text

RESTful API開発 func userHandler(w http.ResponseWriter, r *http.Request) { user := User{Name: "Alice", Age: 30} w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) } var user User err := json.NewDecoder(r.Body).Decode(&user) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } JSONレスポンスの生成: ▶ リクエストのパース: ▶ 78

Slide 79

Slide 79 text

用語辞書 ハンドラー:HTTPリクエストを処理する関数 ▶ ルーティング:URLパスに基づいてリクエストを適切なハンドラーに振り分けること ▶ ミドルウェア:HTTPリクエスト/レスポンスの処理の前後に実行される関数 ▶ テンプレートエンジン:動的にHTMLを生成するためのツール ▶ RESTful API:REpresentational State Transferの原則に基づいて設計されたAPI ▶ 79

Slide 80

Slide 80 text

さいごに Goは、シンプルさと効率性を重視して設計された現代的なプログラミング言語です。その特徴的な並行処理モデル、強力 な標準ライブラリ、そして優れたパフォーマンスにより、特にバックエンド開発やシステムプログラミングの分野で人気 を集めています。 ▶ この総合ガイドでは、Go言語の基本から応用まで幅広くカバーしました。言語の特徴、文法、並行処理、エラー処理、 テスト、Web開発など、Goプログラミングの主要な側面を学びました。 ▶ Happy coding with Go! ▶ 80