Go言語入門:言語仕様 -Vol.43-

スポンサーリンク
Go言語入門:言語仕様 -Vol.43- 用語解説
Go言語入門:言語仕様 -Vol.43-
この記事は約5分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

本日は、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言語の言語仕様について解説しました。

よっしー
よっしー

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

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました