言語概要と設計思想
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())
}