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

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

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

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

スポンサーリンク

背景

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

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

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

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

Lexical elements(字句要素)

Comments(コメント)

コメントはプログラムの説明文として機能します。コメントには2つの形式があります。

  1. 行コメントは文字列//で始まり、行末で終わります。
  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
}

良いコメントの原則:

  1. なぜ(Why) を説明する(コードを見れば何を(What) しているかは分かる)
  2. 複雑なロジックの意図を説明する
  3. 将来の自分や他の開発者のために書く
  4. コードで表現できることはコメントにしない

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の合計

まとめ: コメントで覚えておくべきこと

  1. 行コメント(//) → 行末まで。短い説明に便利
  2. 一般コメント(/* */) → 複数行にわたる説明に便利
  3. 文字列やルーンの中ではコメントにならない
  4. コメントはネストできない
  5. 改行なしの一般コメント → スペース、その他 → 改行
  6. 良いコメントは「なぜ」を説明する
  7. 関数・型の直前のコメントは自動ドキュメント化される

実用的なアドバイス:

  • 日常的には**行コメント(//)**を使うのが一般的
  • 大きなブロックの説明には一般コメント(/* */)
  • 一時的なコード無効化には行コメントが安全(ネストの問題がない)
  • 公開する関数にはGodoc形式のコメントを書く習慣をつける
// 実用的なコメント例
package main

import "fmt"

// ProcessOrder は注文を処理します。
// 在庫チェック、決済処理、配送手配を行います。
func ProcessOrder(orderID int) error {
    // TODO: 在庫チェックを実装
    // FIXME: 決済エラー時のリトライ処理が必要
    
    fmt.Printf("注文 %d を処理中...\n", orderID)
    return nil
}

コメントは、未来の自分や他の開発者への思いやりです。適切に使って、読みやすいコードを書きましょう!

おわりに 

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

よっしー
よっしー

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

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

コメント

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