Go(Golang)は、Googleが開発したシンプルで高速なプログラミング言語です。
読みやすさと処理速度のバランスが良く、Web開発やCLIツール、ネットワークプログラミング、マイクロサービスで注目を集めています。
「GoってCっぽいけど違いは?」「基本の書き方をざっくり知りたい!」「他の言語との違いは?」
そんな方のために、この記事ではGo言語の基本構文を表とコード例でコンパクトに紹介します。
Go言語の特徴と他言語との違い

Go言語の主な特徴
特徴 | 説明 | メリット |
---|---|---|
コンパイル型 | 実行前にバイナリファイルを生成 | 高速実行、配布が簡単 |
静的型付け | 変数の型をコンパイル時にチェック | バグの早期発見、IDE支援 |
シンプルな文法 | 必要最小限のキーワード | 学習コストが低い |
並行処理 | goroutineによる軽量スレッド | 高効率な並行プログラム |
ガベージコレクション | 自動メモリ管理 | メモリリーク防止 |
高速コンパイル | 大規模プロジェクトでも素早くビルド | 開発効率向上 |
他の言語との比較
項目 | Go | Python | Java | C++ |
---|---|---|---|---|
学習難易度 | 低 | 低 | 中 | 高 |
実行速度 | 高速 | 普通 | 高速 | 最高速 |
並行処理 | 簡単 | 複雑 | 複雑 | 複雑 |
メモリ管理 | 自動 | 自動 | 自動 | 手動 |
コンパイル | 高速 | 不要 | 普通 | 遅い |
Goが適している用途
得意分野:
- Webサーバー・API開発
- CLIツール作成
- マイクロサービス
- ネットワークプログラミング
- DevOpsツール
不得意分野:
- GUI アプリケーション
- 数値計算・科学計算
- ゲーム開発
- 機械学習
ポイント: Goは「シンプルで実用的」な構文が最大の魅力です。
Go言語基本構文一覧【完全版】

基本構文まとめ表
構文項目 | 書き方 | 例 | 補足 |
---|---|---|---|
パッケージ宣言 | package main | 必ず最上部に書く | 実行可能なファイルはmain |
インポート | import "fmt" | 複数は括弧でまとめる | 標準・外部パッケージの利用 |
エントリーポイント | func main() {} | 実行開始点 | 引数・戻り値なし |
変数宣言 | var x int = 10 | := でも可能 | ゼロ値で初期化 |
定数宣言 | const Pi = 3.14 | 値は変更不可 | コンパイル時に決定 |
条件分岐 | if , else | if x > 10 {} | カッコ不要、波カッコ必須 |
ループ | for | for i := 0; i < 5; i++ {} | whileに相当する形も可 |
関数定義 | func add(a, b int) int | 複数戻り値も可 | 型は後置 |
配列 | [5]int{1, 2, 3, 4, 5} | サイズ固定 | 長さは型の一部 |
スライス | []int{1, 2, 3} | サイズ可変 | 動的配列 |
マップ | map[string]int{"a":1} | 連想配列型 | key-valueペア |
構造体 | type Person struct {} | フィールド定義可能 | オブジェクト指向の基本 |
Go特有の書き方ルール
重要なルール:
ルール | 説明 | 例 |
---|---|---|
パッケージ名 | 小文字、短く、名詞 | main , fmt , http |
関数名 | 大文字始まり=public、小文字=private | Println() (public), println() (private) |
変数名 | キャメルケース | userName , maxCount |
定数名 | キャメルケース | MaxRetries , DefaultTimeout |
波カッコ | 同じ行に開く | if condition { |
Hello, Worldから始めよう

最もシンプルな例
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
詳細解説:
行 | コード | 意味 |
---|---|---|
1 | package main | 実行可能なGoプログラムであることを宣言 |
3 | import "fmt" | 標準出力関数を使うためのパッケージをインポート |
5 | func main() { | プログラムの実行開始点となる関数 |
6 | fmt.Println("Hello, World!") | 文字列を出力(改行付き) |
実行方法
# ファイル保存: hello.go
go run hello.go
# またはコンパイルしてから実行
go build hello.go
./hello
複数のインポート
package main
import (
"fmt"
"time"
"math"
)
func main() {
fmt.Println("現在時刻:", time.Now())
fmt.Println("円周率:", math.Pi)
}
変数と定数の完全ガイド
変数宣言の方法
方法1:var キーワード(基本形)
var age int = 25 // 型と初期値を明示
var name string = "Alice"
var isStudent bool = true
方法2:型推論
var age = 25 // 型は自動推論(int)
var name = "Alice" // 型は自動推論(string)
方法3:短縮記法(関数内のみ)
func main() {
age := 25 // var age = 25 と同じ
name := "Alice" // var name = "Alice" と同じ
}
方法4:複数変数の同時宣言
var (
name string = "Alice"
age int = 25
height float64 = 165.5
)
// または
name, age := "Bob", 30
Goの基本データ型
カテゴリ | 型 | サイズ | 例 |
---|---|---|---|
整数 | int , int8 , int16 , int32 , int64 | 環境依存〜64bit | 42 , -10 |
符号なし整数 | uint , uint8 , uint16 , uint32 , uint64 | 環境依存〜64bit | 100 |
浮動小数点 | float32 , float64 | 32bit, 64bit | 3.14 , 2.718 |
真偽値 | bool | 1bit | true , false |
文字列 | string | 可変長 | "Hello" |
バイト | byte | 8bit | 'A' |
ルーン | rune | 32bit | 'あ' |
ゼロ値(初期値)
var i int // 0
var f float64 // 0.0
var b bool // false
var s string // ""(空文字列)
var p *int // nil(ポインタ)
定数の宣言
const Pi = 3.14159
const (
StatusOK = 200
StatusNotFound = 404
StatusInternalServerError = 500
)
// 型付き定数
const MaxRetries int = 3
iota(連番定数):
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
条件分岐(if文)の書き方

基本的なif文
age := 20
if age >= 18 {
fmt.Println("成人です")
} else {
fmt.Println("未成年です")
}
else if の使用
score := 85
if score >= 90 {
fmt.Println("優秀")
} else if score >= 70 {
fmt.Println("良好")
} else if score >= 60 {
fmt.Println("合格")
} else {
fmt.Println("不合格")
}
if文での変数初期化(Go特有)
// 変数を宣言してから条件チェック
if num := getRandomNumber(); num > 50 {
fmt.Printf("%d は50より大きい\n", num)
} else {
fmt.Printf("%d は50以下\n", num)
}
// numはif文のスコープ内でのみ有効
論理演算子
age := 25
hasLicense := true
// AND演算子
if age >= 18 && hasLicense {
fmt.Println("運転できます")
}
// OR演算子
if age < 18 || !hasLicense {
fmt.Println("運転できません")
}
// NOT演算子
if !hasLicense {
fmt.Println("免許を取得してください")
}
ループ(for文)の完全ガイド
基本的なfor文(C言語スタイル)
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// 出力: 0, 1, 2, 3, 4
while文相当(条件のみ)
i := 0
for i < 5 {
fmt.Println(i)
i++
}
無限ループ
for {
fmt.Println("無限ループ")
break // breakで抜ける
}
range文(配列・スライス)
numbers := []int{10, 20, 30, 40, 50}
// インデックスと値の両方
for index, value := range numbers {
fmt.Printf("index: %d, value: %d\n", index, value)
}
// 値のみ
for _, value := range numbers {
fmt.Printf("value: %d\n", value)
}
// インデックスのみ
for index := range numbers {
fmt.Printf("index: %d\n", index)
}
range文(マップ)
scores := map[string]int{"Alice": 90, "Bob": 80, "Charlie": 95}
for name, score := range scores {
fmt.Printf("%s: %d点\n", name, score)
}
range文(文字列)
text := "Hello"
for index, char := range text {
fmt.Printf("index: %d, char: %c\n", index, char)
}
break と continue
for i := 0; i < 10; i++ {
if i == 3 {
continue // 3をスキップ
}
if i == 7 {
break // 7で終了
}
fmt.Println(i)
}
// 出力: 0, 1, 2, 4, 5, 6
関数の定義と使い方

基本的な関数定義
func add(a int, b int) int {
return a + b
}
// 同じ型の引数は省略可能
func multiply(a, b int) int {
return a * b
}
func main() {
sum := add(3, 4)
product := multiply(5, 6)
fmt.Printf("3 + 4 = %d\n", sum) // 7
fmt.Printf("5 × 6 = %d\n", product) // 30
}
複数戻り値(Go特有)
func divide(a, b int) (int, int) {
quotient := a / b
remainder := a % b
return quotient, remainder
}
func main() {
q, r := divide(10, 3)
fmt.Printf("10 ÷ 3 = %d 余り %d\n", q, r)
}
名前付き戻り値
func calculate(a, b int) (sum, product int) {
sum = a + b
product = a * b
return // 名前付き戻り値は自動で返される
}
エラーハンドリング(Go特有)
import (
"errors"
"fmt"
)
func safeDivide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("ゼロで割ることはできません")
}
return a / b, nil
}
func main() {
result, err := safeDivide(10, 0)
if err != nil {
fmt.Printf("エラー: %v\n", err)
} else {
fmt.Printf("結果: %f\n", result)
}
}
可変長引数
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
func main() {
fmt.Println(sum(1, 2, 3)) // 6
fmt.Println(sum(1, 2, 3, 4, 5)) // 15
}
関数を値として扱う
func main() {
// 関数を変数に代入
operation := add
result := operation(3, 4)
fmt.Println(result) // 7
// 無名関数
multiply := func(a, b int) int {
return a * b
}
fmt.Println(multiply(3, 4)) // 12
}
配列・スライス・マップの完全ガイド
配列(固定長)
// 宣言方法1:サイズと初期値を指定
var numbers [5]int = [5]int{1, 2, 3, 4, 5}
// 宣言方法2:サイズを自動計算
numbers := [...]int{1, 2, 3, 4, 5}
// 宣言方法3:部分的な初期化
var matrix [3][3]int // 2次元配列
func main() {
fmt.Println(numbers[0]) // 1
fmt.Println(len(numbers)) // 5
// 配列の操作
numbers[0] = 10
fmt.Println(numbers) // [10 2 3 4 5]
}
スライス(動的配列)
// 宣言方法1:リテラル
numbers := []int{1, 2, 3, 4, 5}
// 宣言方法2:make関数
slice := make([]int, 5) // 長さ5、容量5
slice2 := make([]int, 3, 10) // 長さ3、容量10
func main() {
// 要素の追加
numbers = append(numbers, 6, 7, 8)
fmt.Println(numbers) // [1 2 3 4 5 6 7 8]
// スライス操作
fmt.Println(numbers[1:4]) // [2 3 4](インデックス1〜3)
fmt.Println(numbers[:3]) // [1 2 3](最初から3つ)
fmt.Println(numbers[3:]) // [4 5 6 7 8](3から最後まで)
// 長さと容量
fmt.Printf("長さ: %d, 容量: %d\n", len(numbers), cap(numbers))
}
スライスの高度な操作
func main() {
// スライスのコピー
original := []int{1, 2, 3, 4, 5}
copied := make([]int, len(original))
copy(copied, original)
// スライスの削除(特定要素)
index := 2 // インデックス2の要素を削除
numbers := []int{1, 2, 3, 4, 5}
numbers = append(numbers[:index], numbers[index+1:]...)
fmt.Println(numbers) // [1 2 4 5]
}
マップ(連想配列)
// 宣言方法1:リテラル
scores := map[string]int{
"Alice": 90,
"Bob": 80,
"Charlie": 95,
}
// 宣言方法2:make関数
ages := make(map[string]int)
func main() {
// 値の追加・更新
scores["David"] = 85
scores["Alice"] = 92 // 更新
// 値の取得
aliceScore := scores["Alice"]
fmt.Println("Aliceのスコア:", aliceScore)
// 存在チェック
score, exists := scores["Eve"]
if exists {
fmt.Printf("Eveのスコア: %d\n", score)
} else {
fmt.Println("Eveのデータはありません")
}
// 値の削除
delete(scores, "Bob")
// 全要素の表示
for name, score := range scores {
fmt.Printf("%s: %d\n", name, score)
}
}
構造体(struct)とメソッド

基本的な構造体
type Person struct {
Name string
Age int
Email string
}
func main() {
// 構造体の作成方法1
p1 := Person{
Name: "Alice",
Age: 25,
Email: "alice@example.com",
}
// 構造体の作成方法2
p2 := Person{"Bob", 30, "bob@example.com"}
// フィールドアクセス
fmt.Printf("名前: %s, 年齢: %d\n", p1.Name, p1.Age)
// フィールドの更新
p1.Age = 26
}
構造体のメソッド
type Rectangle struct {
Width float64
Height float64
}
// メソッドの定義
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
// ポインタレシーバー(値を変更する場合)
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
func main() {
rect := Rectangle{Width: 10, Height: 5}
fmt.Printf("面積: %.2f\n", rect.Area()) // 50.00
fmt.Printf("周囲: %.2f\n", rect.Perimeter()) // 30.00
rect.Scale(2)
fmt.Printf("拡大後の面積: %.2f\n", rect.Area()) // 200.00
}
構造体の埋め込み(継承的な使い方)
type Animal struct {
Name string
Age int
}
func (a Animal) Speak() {
fmt.Printf("%s が鳴いています\n", a.Name)
}
type Dog struct {
Animal // 埋め込み
Breed string
}
func (d Dog) Bark() {
fmt.Printf("%s がワンワン鳴いています\n", d.Name)
}
func main() {
dog := Dog{
Animal: Animal{Name: "ポチ", Age: 3},
Breed: "柴犬",
}
dog.Speak() // 埋め込まれたメソッドを使用
dog.Bark() // 独自のメソッドを使用
}
ポインタの基本
ポインタとは
func main() {
x := 10
// ポインタの宣言
var p *int = &x // xのアドレスを取得
fmt.Printf("xの値: %d\n", x) // 10
fmt.Printf("xのアドレス: %p\n", &x) // 0x...
fmt.Printf("pの値(アドレス): %p\n", p) // 0x...
fmt.Printf("pが指す値: %d\n", *p) // 10(デリファレンス)
// ポインタ経由で値を変更
*p = 20
fmt.Printf("変更後のx: %d\n", x) // 20
}
関数でのポインタ使用
// 値渡し(元の値は変更されない)
func incrementValue(x int) {
x++
}
// ポインタ渡し(元の値が変更される)
func incrementPointer(x *int) {
*x++
}
func main() {
num := 10
incrementValue(num)
fmt.Println("値渡し後:", num) // 10(変更されない)
incrementPointer(&num)
fmt.Println("ポインタ渡し後:", num) // 11(変更される)
}
インターフェース(interface)
基本的なインターフェース
type Shape 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)
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14159 * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * 3.14159 * c.Radius
}
func printShapeInfo(s Shape) {
fmt.Printf("面積: %.2f, 周囲: %.2f\n", s.Area(), s.Perimeter())
}
func main() {
rect := Rectangle{Width: 10, Height: 5}
circle := Circle{Radius: 3}
printShapeInfo(rect) // 面積: 50.00, 周囲: 30.00
printShapeInfo(circle) // 面積: 28.27, 周囲: 18.85
}
エラーハンドリング
基本的なエラーハンドリング
import (
"errors"
"fmt"
)
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Printf("エラーが発生しました: %v\n", err)
return
}
fmt.Printf("結果: %f\n", result)
}
カスタムエラー型
type ValidationError struct {
Field string
Message string
}
func (e ValidationError) Error() string {
return fmt.Sprintf("validation error in field '%s': %s", e.Field, e.Message)
}
func validateAge(age int) error {
if age < 0 {
return ValidationError{
Field: "age",
Message: "age cannot be negative",
}
}
if age > 150 {
return ValidationError{
Field: "age",
Message: "age cannot be greater than 150",
}
}
return nil
}
実践的なプログラム例
簡単な計算機
package main
import (
"fmt"
"strconv"
"os"
)
func calculator(operation string, a, b float64) (float64, error) {
switch operation {
case "+":
return a + b, nil
case "-":
return a - b, nil
case "*":
return a * b, nil
case "/":
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
default:
return 0, fmt.Errorf("unknown operation: %s", operation)
}
}
func main() {
if len(os.Args) != 4 {
fmt.Println("使用法: calculator <数値1> <演算子> <数値2>")
return
}
a, err := strconv.ParseFloat(os.Args[1], 64)
if err != nil {
fmt.Printf("数値1の解析エラー: %v\n", err)
return
}
operation := os.Args[2]
b, err := strconv.ParseFloat(os.Args[3], 64)
if err != nil {
fmt.Printf("数値2の解析エラー: %v\n", err)
return
}
result, err := calculator(operation, a, b)
if err != nil {
fmt.Printf("計算エラー: %v\n", err)
return
}
fmt.Printf("%.2f %s %.2f = %.2f\n", a, operation, b, result)
}
TODOリスト管理
package main
import "fmt"
type Todo struct {
ID int
Title string
Completed bool
}
type TodoList struct {
todos []Todo
nextID int
}
func NewTodoList() *TodoList {
return &TodoList{
todos: make([]Todo, 0),
nextID: 1,
}
}
func (tl *TodoList) Add(title string) {
todo := Todo{
ID: tl.nextID,
Title: title,
Completed: false,
}
tl.todos = append(tl.todos, todo)
tl.nextID++
}
func (tl *TodoList) Complete(id int) bool {
for i := range tl.todos {
if tl.todos[i].ID == id {
tl.todos[i].Completed = true
return true
}
}
return false
}
func (tl *TodoList) List() {
if len(tl.todos) == 0 {
fmt.Println("TODOはありません")
return
}
for _, todo := range tl.todos {
status := "未完了"
if todo.Completed {
status = "完了"
}
fmt.Printf("[%d] %s (%s)\n", todo.ID, todo.Title, status)
}
}
func main() {
todoList := NewTodoList()
todoList.Add("Go言語を学ぶ")
todoList.Add("買い物に行く")
todoList.Add("メールを返信する")
fmt.Println("=== TODOリスト ===")
todoList.List()
fmt.Println("\n=== TODO完了 ===")
todoList.Complete(1)
todoList.List()
}
よくある質問と回答

Q: GoとPythonの主な違いは?
A: パフォーマンスと型システムが大きく異なります
項目 | Go | Python |
---|---|---|
型システム | 静的型付け | 動的型付け |
実行速度 | コンパイル言語で高速 | インタープリター言語で普通 |
メモリ管理 | ガベージコレクション | ガベージコレクション |
並行処理 | goroutine(簡単) | threading(複雑) |
学習コスト | 中程度 | 低い |
Q: Goはオブジェクト指向言語ですか?
A: 厳密にはオブジェクト指向ではありませんが、似た機能を提供します
Goには以下の特徴があります:
- クラスはないが、構造体とメソッドで同様の機能
- 継承はないが、埋め込みで似た効果
- インターフェースによる抽象化
- ポリモーフィズムをインターフェースで実現
Q: なぜGoには例外処理がないのですか?
A: 明示的なエラーハンドリングを推奨するGoの設計思想です
// Go方式:明示的なエラーチェック
result, err := someFunction()
if err != nil {
// エラー処理
return err
}
// 他言語の例外方式と比較して:
// - エラーが見える化される
// - 処理の流れが明確
// - 予期しないクラッシュが少ない
Q: goroutine(並行処理)の基本的な使い方は?
A: go
キーワードで簡単に並行実行できます
package main
import (
"fmt"
"time"
)
func worker(id int) {
for i := 0; i < 3; i++ {
fmt.Printf("Worker %d: %d\n", id, i)
time.Sleep(time.Millisecond * 500)
}
}
func main() {
// 並行実行
go worker(1)
go worker(2)
// メインgoroutineを少し待つ
time.Sleep(time.Second * 2)
fmt.Println("完了")
}
学習の次のステップ
初級から中級へ
マスターすべき追加概念:
概念 | 重要度 | 説明 |
---|---|---|
goroutine & channel | 高 | 並行プログラミングの基本 |
パッケージ作成 | 高 | 再利用可能なコードの構成 |
テスト | 高 | testing パッケージの使用 |
JSON処理 | 中 | Web APIでよく使用 |
ファイルI/O | 中 | ファイル読み書きの基本 |
HTTP サーバー | 中 | Web開発の基礎 |
推奨学習リソース
公式リソース:
- Go Tour – インタラクティブな学習
- Effective Go – ベストプラクティス
- Go Blog – 最新情報
実践プロジェクト案:
- CLIツール作成 – ファイル操作、フラグ解析
- REST API サーバー – HTTP、JSON、データベース
- Web スクレイピング – HTTP クライアント、HTML パース
- チャットアプリ – WebSocket、goroutine
開発環境のセットアップ
推奨エディタ・IDE:
- VS Code + Go拡張
- GoLand (JetBrains)
- Vim/Neovim + Go プラグイン
便利なツール:
# コードフォーマット
go fmt ./...
# コード検査
go vet ./...
# 依存関係管理
go mod init project-name
go mod tidy
# テスト実行
go test ./...
# ベンチマーク
go test -bench=.
まとめ:Go言語の基本構文をマスターしよう!
今回学んだ重要な構文:
項目 | 重要ポイント |
---|---|
パッケージ | package main から始める |
変数 | var または:= 、静的型付け |
制御構文 | if 、for (whileなし) |
関数 | 複数戻り値、エラーハンドリング |
データ構造 | 配列、スライス、マップ、構造体 |
メソッド | 構造体にメソッドを定義可能 |
インターフェース | 抽象化とポリモーフィズム |
Goの特徴を活かすポイント:
- シンプルな文法を意識したコード作成
- エラーハンドリングを明示的に行う
- goroutineで並行処理を活用
- インターフェースで疎結合な設計
コメント