
こんにちは。よっしーです(^^)
本日は、Go言語の言語仕様について解説しています。
背景
Go言語を学び始めて、公式の「The Go Programming Language Specification(言語仕様書)」を開いてみたものの、「英語で書かれていて読むのが大変…」「専門用語ばかりで何を言っているのかわからない…」と感じたことはありませんか? 実は、多くのGo初心者が同じ壁にぶつかっています。
言語仕様書は、Go言語の「正式な取扱説明書」のような存在です。プログラミング言語がどのように動くのか、どんなルールで書くべきなのかが詳しく書かれていますが、その分、初めて読む人には難しく感じられるのも事実です。
そこでこの記事では、言語仕様書の導入部分を丁寧な日本語訳とともに、初心者の方でも理解しやすい補足説明を加えてお届けします。「強く型付けされている」「ガベージコレクション」「並行プログラミング」といった専門用語も、具体例を交えながらわかりやすく解説していきます。
言語仕様書は難しそうに見えますが、一つひとつの概念を丁寧に読み解いていけば、必ず理解できます。一緒に、Go言語の基礎をしっかり学んでいきましょう!
Lexical elements(字句要素)
Comments(コメント)
コメントはプログラムの説明文として機能します。コメントには2つの形式があります。
- 行コメントは文字列
//で始まり、行末で終わります。 - 一般コメントは文字列
/*で始まり、最初に現れる文字列*/で終わります。
コメントは、ルーン(文字)リテラルや文字列リテラルの内部、または別のコメントの内部で開始することはできません。改行を含まない一般コメントは空白(スペース)のように振る舞います。その他のコメントは改行のように振る舞います。
解説
コメントとは何か?
コメントは、プログラムの中に書く「メモ」や「説明文」です。コンピュータは実行時にコメントを完全に無視するので、自由に日本語で説明を書くことができます。
たとえ話: 料理のレシピに書かれた「ここで火加減に注意!」「この工程は省略可能」といったメモのようなものです。料理を作る上で必須ではありませんが、作る人(プログラマー)が理解しやすくするために書きます。
package main
import "fmt"
func main() {
// これはコメントです。プログラムは実行されません。
fmt.Println("Hello, World!") // 画面に文字を表示
}
コメントの2つの形式
1. 行コメント(Line comments)
行コメントは//で始まり、その行の終わりまでがコメントになります。
package main
import "fmt"
func main() {
// これは1行コメントです
fmt.Println("Hello") // ここもコメント
// 複数行にわたって書く場合は
// 各行の先頭に//を付けます
// こうすることで、何行でも説明を書けます
var age int = 25 // 年齢を保存する変数
}
使用場面:
- 短い説明やメモ
- コードの右側に補足説明を書く
- 一時的にコードを無効化(コメントアウト)する
package main
func main() {
// デバッグ用の出力
// fmt.Println("デバッグ中...") // 一時的に無効化
// 正式な処理
processData()
}
たとえ話: 行コメントは、ノートの余白に書く短いメモのようなものです。1行で完結する簡潔な説明に向いています。
2. 一般コメント(General comments)
一般コメントは/*で始まり、*/で終わります。複数行にわたるコメントを書くときに便利です。
package main
import "fmt"
/*
これは一般コメントです。
複数行にわたって
詳しい説明を書くことができます。
*/
func main() {
fmt.Println("Hello")
}
使用場面:
- 関数やパッケージの詳しい説明
- 大きなコードブロックを一時的に無効化
- ドキュメント生成ツール用のコメント
package main
/*
calculateTotal関数は、商品の合計金額を計算します。
引数:
- items: 商品のスライス
- taxRate: 消費税率(0.1 = 10%)
戻り値:
- 税込み合計金額
*/
func calculateTotal(items []int, taxRate float64) float64 {
var total float64
for _, price := range items {
total += float64(price)
}
return total * (1 + taxRate)
}
1行で使うこともできます:
package main
func main() {
var x int = 10 /* これは1行の一般コメント */ + 5
// xは15になる
}
たとえ話: 一般コメントは、本の序文や詳しい注釈のようなものです。まとまった説明が必要なときに使います。
コメントのルールと制約
ルール1: リテラルの中では開始できない
文字列リテラルやルーンリテラルの中では、//や/*はコメントとして扱われません。ただの文字列の一部になります。
package main
import "fmt"
func main() {
// 正しい例: これは文字列の一部であり、コメントではない
url := "https://example.com" // "//example.com"の部分はコメントではない
comment := "これは /* 本当に */ 文字列です"
fmt.Println(url)
fmt.Println(comment)
// 出力: https://example.com
// 出力: これは /* 本当に */ 文字列です
}
ルーンリテラルの例:
package main
import "fmt"
func main() {
var slash rune = '/' // スラッシュ文字
// 上記の'//'はコメントではなく、'/'という文字を表している
fmt.Printf("%c\n", slash) // 出力: /
}
たとえ話: 小説の中で「//」という記号が出てきても、それは物語の一部であって、作者のメモではありませんよね。同じように、文字列の中のコメント記号は、ただの文字です。
ルール2: コメントの中でコメントを開始できない(ネストできない)
コメントの中で別のコメントを開始することはできません。
package main
func main() {
// これは正しいコメント
// // これも正しい(ただの2重スラッシュ)
/* これは一般コメント */
/*
これは複数行コメント
/* ここでネストしようとしても無効 */
←この行は実はコメント外になってしまう!
*/
// 正しいネスト風の書き方:
/*
外側のコメント
// 内側は行コメント風に見えるが、
// 実際はただの文字列として扱われる
*/
}
注意: C言語などと違い、Goの一般コメントはネストできません。複数行をコメントアウトするときは、行コメント//を各行に付けるか、エディタのコメント機能を使いましょう。
package main
func main() {
// 複数行をコメントアウトする推奨方法
// var x int = 10
// var y int = 20
// fmt.Println(x + y)
}
コメントの振る舞い: スペースと改行
コメントは、コンパイラによって特定の空白文字に置き換えられます。
改行を含まない一般コメント → スペースとして扱われる
package main
import "fmt"
func main() {
var x/*ここにコメント*/int = 10
// 上記は次と同じ:
// var x int = 10
fmt.Println(x)
}
コンパイラは/*ここにコメント*/を1つのスペースに置き換えます。結果としてvar x int = 10となります。
その他のコメント → 改行として扱われる
package main
import "fmt"
func main() {
var x int = 10 // 行コメント
var y int = 20
/*
複数行コメント
*/
var z int = 30
fmt.Println(x, y, z)
}
- 行コメント
//は改行として扱われる - 改行を含む一般コメント
/* ... */も改行として扱われる
実用上の意味: これにより、コメントを書いても文の区切りが正しく認識されます。
package main
func main() {
x := 10 // コメント
y := 20 // ここで改行と同じ扱いになるので、次の文が始まる
}
実践的なコメントの書き方
良いコメントの例
package main
import "fmt"
// ユーザー情報を表す構造体
type User struct {
ID int // ユーザーID
Name string // ユーザー名
Age int // 年齢
}
// calculateDiscount は年齢に応じた割引率を計算します。
// 65歳以上: 20%割引
// 18歳未満: 10%割引
// その他: 割引なし
func calculateDiscount(age int) float64 {
if age >= 65 {
return 0.20 // シニア割引
} else if age < 18 {
return 0.10 // 学生割引
}
return 0.0 // 割引なし
}
func main() {
user := User{
ID: 1,
Name: "太郎",
Age: 70,
}
discount := calculateDiscount(user.Age)
fmt.Printf("割引率: %.0f%%\n", discount*100)
}
避けるべきコメントの例
package main
func main() {
// xに10を代入 ← コードを見れば分かるので不要
x := 10
// xとyを足す ← 自明なので不要
z := x + y
// より良いコメントの例:
// 消費税込みの金額を計算(税率10%)
totalWithTax := price * 1.10
}
良いコメントの原則:
- なぜ(Why) を説明する(コードを見れば何を(What) しているかは分かる)
- 複雑なロジックの意図を説明する
- 将来の自分や他の開発者のために書く
- コードで表現できることはコメントにしない
Godocコメント(ドキュメント生成用)
Goには、コメントから自動的にドキュメントを生成するgodocというツールがあります。関数や型の直前に書いたコメントがドキュメントになります。
package main
import "fmt"
// Add は2つの整数を足し算します。
//
// 引数:
// a: 1つ目の数
// b: 2つ目の数
//
// 戻り値:
// aとbの合計
func Add(a, b int) int {
return a + b
}
// User はシステムのユーザーを表します。
type User struct {
// Name はユーザーの名前です。
Name string
// Age はユーザーの年齢です。
Age int
}
func main() {
result := Add(10, 20)
fmt.Println(result)
}
このようなコメントを書いておくと、go docコマンドでドキュメントを表示できます:
$ go doc Add
func Add(a, b int) int
Add は2つの整数を足し算します。
引数:
a: 1つ目の数
b: 2つ目の数
戻り値:
aとbの合計
まとめ: コメントで覚えておくべきこと
- 行コメント(
//) → 行末まで。短い説明に便利 - 一般コメント(
/* */) → 複数行にわたる説明に便利 - 文字列やルーンの中ではコメントにならない
- コメントはネストできない
- 改行なしの一般コメント → スペース、その他 → 改行
- 良いコメントは「なぜ」を説明する
- 関数・型の直前のコメントは自動ドキュメント化される
実用的なアドバイス:
- 日常的には**行コメント(
//)**を使うのが一般的 - 大きなブロックの説明には一般コメント(
/* */) - 一時的なコード無効化には行コメントが安全(ネストの問題がない)
- 公開する関数にはGodoc形式のコメントを書く習慣をつける
// 実用的なコメント例
package main
import "fmt"
// ProcessOrder は注文を処理します。
// 在庫チェック、決済処理、配送手配を行います。
func ProcessOrder(orderID int) error {
// TODO: 在庫チェックを実装
// FIXME: 決済エラー時のリトライ処理が必要
fmt.Printf("注文 %d を処理中...\n", orderID)
return nil
}
コメントは、未来の自分や他の開発者への思いやりです。適切に使って、読みやすいコードを書きましょう!
おわりに
本日は、Go言語の言語仕様について解説しました。

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)

コメント