
こんにちは。よっしーです(^^)
本日は、Go言語の言語仕様について解説しています。
背景
Go言語を学び始めて、公式の「The Go Programming Language Specification(言語仕様書)」を開いてみたものの、「英語で書かれていて読むのが大変…」「専門用語ばかりで何を言っているのかわからない…」と感じたことはありませんか? 実は、多くのGo初心者が同じ壁にぶつかっています。
言語仕様書は、Go言語の「正式な取扱説明書」のような存在です。プログラミング言語がどのように動くのか、どんなルールで書くべきなのかが詳しく書かれていますが、その分、初めて読む人には難しく感じられるのも事実です。
そこでこの記事では、言語仕様書の導入部分を丁寧な日本語訳とともに、初心者の方でも理解しやすい補足説明を加えてお届けします。「強く型付けされている」「ガベージコレクション」「並行プログラミング」といった専門用語も、具体例を交えながらわかりやすく解説していきます。
言語仕様書は難しそうに見えますが、一つひとつの概念を丁寧に読み解いていけば、必ず理解できます。一緒に、Go言語の基礎をしっかり学んでいきましょう!
ブランク識別子(Blank identifier)
ブランク識別子はアンダースコア文字 _ で表されます。通常の(ブランクでない)識別子の代わりとなる匿名のプレースホルダーとして機能し、宣言、オペランド、および代入文において特別な意味を持ちます。
解説
たとえ話
ブランク識別子 _ は、「受け取ったけどすぐにゴミ箱に入れるレシート」 のようなものです。
たとえば、コンビニで買い物をしたとき、商品(欲しい値)は受け取りますが、レシート(不要な値)は「いりません」と断りますよね。Goでは、関数が複数の値を返す場面が非常に多いのですが、そのすべてが必要とは限りません。そんなとき、_ を使って「この値は受け取るけど使いません」と明示的に宣言します。
ポイントは、Goは未使用の変数をコンパイルエラーにする厳格な言語だということです。_ はその厳格さと「不要な値がある現実」を両立させるための仕組みです。
コード例
package main
import "fmt"
// ── 代入文での使用:不要な戻り値を捨てる ──
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("ゼロ除算はできません")
}
return a / b, nil
}
func main() {
// 商だけ欲しい場合、エラーは _ で受け取る
result, _ := divide(10, 2)
fmt.Println("結果:", result) // → 結果: 5
// エラーだけ確認したい場合、商は _ で受け取る
_, err := divide(10, 0)
if err != nil {
fmt.Println("エラー:", err) // → エラー: ゼロ除算はできません
}
}
package main
import "fmt"
// ── range ループでの使用:インデックスまたは値を捨てる ──
func main() {
fruits := []string{"りんご", "みかん", "ぶどう"}
// インデックスだけ欲しい(値は不要)
for i, _ := range fruits {
fmt.Println("番号:", i)
}
// 値だけ欲しい(インデックスは不要)
for _, fruit := range fruits {
fmt.Println("果物:", fruit)
}
}
package main
// ── 宣言での使用:import の副作用だけを利用する ──
import (
"fmt"
// データベースドライバはinit()で登録するだけで直接呼び出さない
// _ を使って「パッケージ名は不要だが、初期化処理は実行してほしい」と伝える
_ "github.com/go-sql-driver/mysql"
)
func main() {
fmt.Println("MySQLドライバが初期化されました")
}
package main
import "fmt"
// ── インターフェースの実装チェックに使うイディオム ──
type Animal interface {
Speak() string
}
type Dog struct{}
func (d Dog) Speak() string {
return "ワン!"
}
// コンパイル時に Dog が Animal を実装しているか確認する
// 実装していなければコンパイルエラーになる
var _ Animal = Dog{}
func main() {
fmt.Println(Dog{}.Speak())
}
よくある間違い・注意点
1. エラーを安易に _ で捨てない
// ❌ 危険:エラーを握りつぶしている
result, _ := doSomethingRisky()
エラーを _ で捨てると、問題が起きても原因が分からなくなります。本番コードではエラーを必ずチェックする習慣をつけましょう。_ でエラーを捨ててよいのは、エラーが起こり得ないことが明白な場合に限ります。
2. _ は「変数」ではない
_ = 42
// fmt.Println(_) // ❌ コンパイルエラー!_ は読み取れない
_ に代入はできますが、後から値を読み取ることはできません。束縛を導入しないため、変数として参照する手段がないのです。
3. _ は何度でも使える
通常の変数は同じブロックで再宣言できませんが、_ は束縛を作らないので何度でも使えます。
// ✅ すべて合法
_ = 1
_ = "hello"
_ = true
まとめ
- ブランク識別子
_は、値を受け取るが使わないことを明示するための特殊な識別子。 - 宣言・代入・オペランドの3つの場面で使える。
_は束縛を導入しないため、変数として参照したり読み取ったりすることはできない。- 実務での代表的な用途は、不要な戻り値の破棄、
importの副作用利用、インターフェース実装のコンパイル時チェック。 - エラー値を
_で捨てるのは便利だが、安易に使うとバグの温床になるので注意が必要。
_ は小さな記号ですが、Goの「未使用の変数は許さない」という設計思想と深く結びついた重要な存在です。使いどころを正しく理解しておくと、クリーンで安全なコードが書けるようになりますよ!
おわりに
本日は、Go言語の言語仕様について解説しました。

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

コメント