🔍

Go言語の省略変数宣言に使われる演算子`:=`の由来は?

2024/10/29に公開

はじめに

Goのプログラミングにおいて特徴的な演算子の一つである「:=」は、新しい変数の宣言と初期化を同時に行えて便利です。ところで、:=の演算子の由来を考えたことはありますか?
この記事では、:=演算子の歴史的ルーツをたどり、Go言語の設計思想に基づいた解釈を紹介します👋。過去の言語からの影響を知ることでGo言語の背景をより理解できるでしょう。

:=の基本的な使い方

次の例ではmsgn:=によって宣言され、それぞれ文字列と整数で初期化されています。

package main

import "fmt"

func main() {
	msg := "Hello, World!"
	n := 42
	fmt.Println(msg, n)
}

この変数宣言および初期化をプログラミング言語Goでは「省略変数宣言」と呼んでいます。

Go言語のルーツ

省略変数宣言のルーツについてお話しする前に少しだけGo言語のルーツに触れたいと思います。
下記の図[1]では各ブロックが言語を表していて、矢印の先がそのブロックの言語の影響先を表しています。

上図での CSP は言語ではなく理論となっています。

省略変数宣言のルーツ💡

先ほどの図でも見たように ALGOL 60は、多くのプログラミング言語の基礎になっています。ALGOLでは、:=は変数への代入を意味しました。
そしてALGOLからの影響を受けたPascalも、同じく:=を代入演算子として採用しました。Pascalは過去に教育用言語として広く使われていたようです。
Goの省略変数宣言は、1960年代のALGOL 60およびその後のPascalといった古典的な言語の影響を受けています。Goでは代入だけではなく宣言の意味も含まれています。

省略変数宣言の注意点🛠️

同じスコープ内で誤って変数を再宣言してしまうことがあります。これを シャドーイング(Shadowing) と呼びます。
以下の例では同じ名前の変数が異なるスコープで使用されています。

package main

import "fmt"

func main() {
    x := 10
    fmt.Println("外側の x:", x) // 10が表示される

    // 内側のスコープで同じ名前の変数を宣言
    if x := 20; x > 15 {
        fmt.Println("内側の x:", x) // 20が表示される
    }

    // 外側の x は影響を受けない
    fmt.Println("外側の x:", x) // 10が表示される
}

👆このコードでは、if 文内で新たに宣言された x が外側のスコープの x を「隠して」います。このような挙動をシャドーイングと言います。

💡 なぜ「シャドーイング」と呼ばれるのか?

シャドーイング(Shadowing)は、直訳すると「影を作る」という意味です。内側のスコープで宣言された変数が、外側のスコープにある同名の変数を「影で隠す」ような挙動をすることから、この名前が付けられました。

おわりに

:=を使った省略変数宣言はシンプルに変数宣言するための手法です。ALGOLやPascalといった過去の言語からの影響を受けつつ、宣言と初期化を一度に行える便利な方法として取り入れられました。
この記事を通して、:=の歴史的な背景と使い方、そして注意点について理解が深まったのではないでしょうか。Go言語の設計思想を知ることで、より良いコードを書くためのヒントを得られるかもしれません🚀。


参考文献

脚注
  1. Alan A. A. Donovan, Brian W. Kernighan. The Go Programming Language. xii p. ↩︎

Discussion