Go言語によるサーバーサイド開発の基礎技術

言語概要と設計思想

GoはGoogleが開発した静的型付けのコンパイル言語であり、特に高並行なサーバーサイドアプリケーションやマイクロサービス向けに設計されています。シンプルな文法と強力なランタイムサポートにより、効率的なシステムプログラミングを実現します。

開発環境構築

各プラットフォーム向けの公式バイナリを取得し、PATHを通すことですぐに利用可能になります。インストール後、go versionコマンドで正常に設定されたことを確認してください。

プログラム基本構成

Goのソースコードは以下の要素で構成されます。

package main

import "fmt"

func main() {
    // 実行ロジック
    fmt.Println("Hello, Go")
}

パッケージ宣言、インポート、関数定義という明確な構造を持ち、go run ファイル名.goで直接実行できます。

データ型体系

基本型としてbool、整数型(int, int8など)、浮動小数点数(float32, float64)、文字列(string)をサポートします。複合型として配列、スライス、マップ、構造体、ポインタ、関数、インターフェース、チャネルが利用可能です。

変数宣言と定数定義

変数は明示的な型指定または型推論で宣言できます。

var userName string = "developer"
var age = 25
score := 98.5 // 短縮宣言

// 複数変数
var (
    host string = "localhost"
    port int    = 8080
)

定数はconstキーワードで定義し、コンパイル時に評価されます。

const Timeout = 30
const (
    StatusOK       = 200
    StatusNotFound = 404
)

制御構文

条件分岐

if文は条件式を括弧で囲む必要がありません。switchは自動的にbreakされるため、明示的なbreakが不要です。selectはチャネル操作に特化した制御構造で、複数のチャネルから準備ができたものを選択します。

// if文例
if score := 85; score >= 80 {
    fmt.Println("合格")
}

// switch文例
switch os := runtime.GOOS; os {
case "darwin":
    fmt.Println("Mac OS")
case "linux":
    fmt.Println("Linux")
default:
    fmt.Println("その他")
}

ループ制御

Goにはforのみが存在しますが、様々な形態で利用できます。

// while型
cnt := 1
for cnt <= 3 {
    fmt.Printf("処理回数: %d\n", cnt)
    cnt++
}

// C言語スタイル
for idx := 0; idx < 5; idx++ {
    if idx%2 == 0 {
        continue
    }
    fmt.Println(idx)
}

// 無限ループ
for {
    fmt.Println("無限ループ")
    break
}

関数定義

関数は複数の戻り値を返せる特徴があります。

func Calculate(x, y int) (int, int) {
    sum := x + y
    diff := x - y
    return sum, diff
}

// 呼び出し例
total, _ := Calculate(10, 5)

スコープ規則

変数の有効範囲は宣言されたブロック内に限定されます。パッケージレベルで宣言された変数は大文字で始めることで他パッケージからアクセス可能になります。

配列とスライス

配列は固定長、スライスは可変長の配列抽象化です。

// 配列
var numbers [3]int = [3]int{1, 2, 3}

// スライス
scores := make([]int, 2, 4)
scores[0] = 85
scores[1] = 92

// 要素追加
scores = append(scores, 78, 95)
fmt.Println(len(scores), cap(scores)) // 4, 4

ポインタ操作

ポインタはメモリアドレスを直接操作します。

value := 42
ptr := &value
fmt.Printf("アドレス: %p, 値: %d\n", ptr, *ptr)

// 未初期化ポインタはnil
var emptyPtr *int
fmt.Println(emptyPtr == nil) // true

構造体定義

複数のフィールドを持つデータ構造を定義できます。

type Product struct {
    ID    int
    Name  string
    Price float64
}

// 初期化
item := Product{ID: 1, Name: "ノートPC", Price: 129800.00}
fmt.Printf("商品名: %s, 価格: %.0f円\n", item.Name, item.Price)

Rangeによるイテレーション

rangeキーワードは配列、スライス、マップ、チャネルを走査します。

// スライス走査
data := []string{"Go", "Python", "Rust"}
for i, v := range data {
    fmt.Printf("%d: %s\n", i, v)
}

// マップ走査
studentScores := map[string]int{"太郎": 85, "花子": 92}
for k, v := range studentScores {
    fmt.Printf("%s: %d点\n", k, v)
}

マップ操作

キー・バリュー型のコレクションです。

// マップ作成
employeeMap := make(map[int]string)
employeeMap[101] = "田中"
employeeMap[102] = "佐藤"

// 値取得
name, exists := employeeMap[101]
if exists {
    fmt.Println(name)
}

// 削除
delete(employeeMap, 102)

再帰関数

関数内で自身を呼び出す再帰処理が可能です。

func Fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    return Fibonacci(n-1) + Fibonacci(n-2)
}

// 呼び出し
result := Fibonacci(7) // 13

型変換

明示的な型変換が必要です。

var x int = 100
var y float64 = float64(x)
var z uint = uint(y)

インターフェース実装

メソッドの集合を定義し、具象型はそのメソッドを実装することでインターフェースを満たします。

type Writer interface {
    Write(data string) error
}

type ConsoleWriter struct{}

func (cw ConsoleWriter) Write(data string) error {
    fmt.Println(data)
    return nil
}

// 使用例
var w Writer = ConsoleWriter{}
w.Write("コンソール出力")

エラーハンドリング

errorインターフェースを実装したカスタムエラー型を定義します。

type NetworkError struct {
    host string
    port int
}

func (ne *NetworkError) Error() string {
    return fmt.Sprintf("接続失敗: %s:%d", ne.host, ne.port)
}

func Connect(host string, port int) error {
    if port <= 0 {
        return &NetworkError{host, port}
    }
    // 接続処理...
    return nil
}

// 呼び出し
if err := Connect("localhost", 0); err != nil {
    fmt.Println(err.Error())
}

タグ: Go golang server-side Backend concurrency

6月9日 18:27 投稿