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

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

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

本日は、Go言語の言語仕様について解説しています。

スポンサーリンク

背景

Go言語を学び始めて、公式の「The Go Programming Language Specification(言語仕様書)」を開いてみたものの、「英語で書かれていて読むのが大変…」「専門用語ばかりで何を言っているのかわからない…」と感じたことはありませんか? 実は、多くのGo初心者が同じ壁にぶつかっています。

言語仕様書は、Go言語の「正式な取扱説明書」のような存在です。プログラミング言語がどのように動くのか、どんなルールで書くべきなのかが詳しく書かれていますが、その分、初めて読む人には難しく感じられるのも事実です。

そこでこの記事では、言語仕様書の導入部分を丁寧な日本語訳とともに、初心者の方でも理解しやすい補足説明を加えてお届けします。「強く型付けされている」「ガベージコレクション」「並行プログラミング」といった専門用語も、具体例を交えながらわかりやすく解説していきます。

言語仕様書は難しそうに見えますが、一つひとつの概念を丁寧に読み解いていけば、必ず理解できます。一緒に、Go言語の基礎をしっかり学んでいきましょう!

Notation(表記法)

構文は、拡張バッカス・ナウア記法(EBNF)の変種を使用して指定されています。

Syntax      = { Production } .
Production  = production_name "=" [ Expression ] "." .
Expression  = Term { "|" Term } .
Term        = Factor { Factor } .
Factor      = production_name | token [ "…" token ] | Group | Option | Repetition .
Group       = "(" Expression ")" .
Option      = "[" Expression "]" .
Repetition  = "{" Expression "}" .

Productionは、項(term)と以下の演算子から構成される式であり、優先順位の高い順に示されています。

|   選択(alternation)
()  グループ化(grouping)
[]  オプション(0回または1回)
{}  繰り返し(0回からn回)

小文字のプロダクション名は、字句(終端)トークンを識別するために使用されます。非終端記号はキャメルケースで表記されます。字句トークンは二重引用符""またはバッククォート``で囲まれます。

a … bという形式は、aからbまでの文字の集合を選択肢として表します。水平省略記号は、仕様書の他の箇所でも、詳しく指定されていないさまざまな列挙やコードスニペットを非公式に示すために使用されます。文字(3つの文字...とは対照的に)は、Go言語のトークンではありません。

[Go 1.xx]という形式のリンクは、説明されている言語機能(またはその一部)が言語バージョン1.xxで変更または追加されたことを示しており、したがってビルドには最低でもその言語バージョンが必要です。詳細については、付録のリンクされたセクションを参照してください。


解説

「表記法」とは何か?

この章では、Go言語の文法ルールがどのように書かれているかを説明しています。プログラミング言語の仕様書では、「こういう書き方が正しい」というルールを正確に表現する必要があります。そのために使われるのが**EBNF(拡張バッカス・ナウア記法)**という記法です。

たとえ話: 料理のレシピ本を想像してください。レシピを書くときに、「材料A、材料B、材料Cを混ぜる」といった手順を書きますが、その「書き方のルール」自体を説明しているのがこの章です。

EBNFって何? なぜ必要なの?

EBNFは、プログラミング言語の文法を数学的に正確に表現するための記法です。普通の日本語や英語で説明すると曖昧になってしまうことも、EBNFを使えば誰が読んでも同じ意味に解釈できます。

たとえば、「変数宣言はvarという単語の後に変数名を書きます」と文章で説明するより、EBNFで書いた方が正確で機械的にも処理しやすくなります。

EBNFの基本ルールを理解しよう

Production(生成規則)とは?

Productionは、文法のルールを定義する1行1行のことです。次のような形式で書かれます。

Production = production_name "=" [ Expression ] "." .

これは「production_nameという名前のルールは、Expressionで定義されますよ」という意味です。

具体例で見てみましょう:

Number = "0" | "1" | "2" | "3" .

これは「Number(数字)は、0123のどれかです」という意味になります。

演算子の意味を覚えよう

EBNFでは、以下の記号が使われます。優先順位の高い順に並んでいます。

記号意味具体例
``選択(どちらか一方)
()グループ化(まとめる)`(“a”
[]オプション(あってもなくてもいい、0回または1回)["x"] → xがあってもなくてもOK
{}繰り返し(0回以上何回でも){"x"} → x, xx, xxx… または何もなし

実際の例で理解しよう:

// Go言語の変数宣言を簡略化したEBNF例
VarDecl = "var" identifier [ "=" Expression ] .

これは次のように読みます:

  • varというキーワードが必ず必要
  • その後に変数名(identifier)が必要
  • = Expression(初期値の代入)はオプション(あってもなくてもいい)

つまり、以下のどちらも正しい構文です:

var x           // 初期値なし
var y = 10      // 初期値あり

{}(繰り返し)の例

ArgumentList = Expression { "," Expression } .

これは「引数リストは、最初に1つのExpressionがあり、その後に,Expressionのペアが0回以上繰り返される」という意味です。

具体的には:

myFunc(a)           // 1つの引数
myFunc(a, b)        // 2つの引数
myFunc(a, b, c)     // 3つの引数

終端記号と非終端記号

小文字のproduction名(終端記号)

終端記号は、これ以上分解できない最小単位のトークン(単語)のことです。小文字で書かれます。

identifier = letter { letter | digit } .

identifier(識別子=変数名など)は、文字で始まり、その後に文字か数字が続く、という具体的な形が決まっています。

CamelCaseのproduction名(非終端記号)

非終端記号は、他のルールを組み合わせて定義される、より大きな構造のことです。キャメルケース(単語の先頭が大文字)で書かれます。

IfStatement = "if" Expression Block .

IfStatementif文全体の構造を表し、その中にExpression(条件式)やBlock(処理ブロック)といった他のルールが含まれます。

トークンの表記方法

ダブルクォート""とバッククォート``

実際にコードに書くキーワードや記号は、引用符で囲まれます。

"var"       // varというキーワード
"+"         // プラス記号
`package`   // packageというキーワード(バッククォートでも可)

a … bという表記

a … bは「aからbまでの範囲」を表します。

digit = "0" … "9" .

これは「digitは0から9までのどれか」という意味です。つまり:

"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

と同じ意味ですが、もっと簡潔に書けます。

注意点: (1文字の省略記号)と...(3つのドット)は別物です。Goのコードでは...(可変長引数など)を使いますが、仕様書の表記ではを使います。

バージョン情報のリンク

仕様書の中に[Go 1.18]のようなリンクがあったら、それは「この機能はGo 1.18で追加または変更されました」という意味です。

たとえば、ジェネリクス(型パラメータ)は[Go 1.18]で追加されたので、Go 1.17以前では使えません。プログラムをビルドするときは、そのバージョン以上が必要になります。

// ジェネリクスの例(Go 1.18以降)
func Min[T comparable](a, b T) T {
    if a < b {
        return a
    }
    return b
}

実践例: 簡単なEBNFを読んでみよう

次のようなEBNF定義があったとします:

Greeting = "Hello" [ "," identifier ] "!" .

これを読み解くと:

  • "Hello"が必ず必要
  • [ "," identifier ]はオプション(あってもなくてもいい)
    • もしあれば、,の後に名前(identifier)が来る
  • 最後に"!"が必ず必要

つまり、次のような文が作れます:

Hello!              // オプション部分なし
Hello, World!       // オプション部分あり
Hello, Taro!        // オプション部分あり

まとめ

この章で学んだことは、Go言語の仕様書を読むための基礎知識です。EBNFは最初は難しく感じるかもしれませんが、次のポイントを押さえておけば大丈夫です:

  1. | → どちらか選ぶ
  2. [] → あってもなくてもいい
  3. {} → 何回でも繰り返せる(0回も可)
  4. 小文字 → 具体的なトークン(終端記号)
  5. CamelCase → 大きな構造(非終端記号)

この知識があれば、仕様書の後半に出てくる文法定義も少しずつ読めるようになります。焦らず、一つずつ慣れていきましょう!

おわりに 

本日は、Go言語の言語仕様について解説しました。

よっしー
よっしー

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

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

コメント

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