Menu

Go言語のHello World:最初のGolangプログラムを1行ずつ解説

GoのHello Worldプログラムを1行ずつ解説します。package main、importブロック、func main、fmt.Println、そして実行方法と初心者が最初に出会うコンパイルエラーまで。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

プログラムの全体です。Runを押してください。

どの行も省略できません。このページの残りでは、それぞれの行が何をしているかを説明します。

1行ずつ見る

package main

Goのファイルはすべて、そのファイルが属するパッケージを示す package 句で始まります。main という名前は特別で、そのパッケージが実行可能なプログラムであることを表します。それ以外の名前(package utilspackage hello)にすると、他のコードからインポートされるライブラリになり、単独では実行できません。

import "fmt"

import は別のパッケージを取り込んで使えるようにします。fmt は標準ライブラリの書式化と出力のパッケージです。インポートした後は、公開された名前にパッケージ名を通してアクセスします。fmt.Printlnfmt.Printffmt.Sprintf のようにです。

複数のパッケージをインポートするときは、1行に1つずつパスを書いたかっこのブロックを使います。

import (
	"fmt"
	"strings"
)

Goは、インポートしたのに使っていないパッケージがあるファイルのコンパイルを拒否します。これで依存関係のリストが正確に保たれます。そして、ほとんどの人が最初に出会うエラーがこれです。

func main()

func は関数を宣言します。main パッケージの main がエントリーポイントです。プログラムは main の開始とともに始まり、main から戻ると終了します。引数も戻り値もありません。コマンドライン引数は os.Args から受け取り、終了コードは os.Exit で返します。

fmt.Println("Hello, World!")

Println は引数を表示し、引数の間に空白を入れ、最後に改行を付けます。名前が大文字で始まっているのは、大文字で始まる名前だけがパッケージの外に公開されるからです。小文字の p で書いた fmt.println はコンパイルエラーになります。

文字列以外も表示する

Println はどんな型の値もいくつでも受け取れます。Printf を使うと書式を制御できます。

%s は文字列に、%d は整数に置き換えられます。PrintfPrint は改行を付けないので、\n を自分で書きます。書式指定子の一覧はfmt.Printfのページにあります。

自分のマシンで実行する

Goをインストールしたら、プログラムを空のフォルダに main.go として保存して実行します。

go run main.go
Hello, World!

go run はファイルを一時的なバイナリにコンパイルして実行します。手元に残して他の場所にコピーできるバイナリを作るには go build を使います。

go mod init example.com/hello
go build
./hello
Hello, World!

go build にはモジュール(go.mod ファイル)が必要で、それは go mod init が作ります。バイナリの名前はモジュールパスの最後の部分になり、ここでは hello です(Windowsでは hello.exe)。runbuildinstall の違いはgo runとgo buildのページで扱っています。

セミコロンはどこへ行ったのか

Goの文法はセミコロンを使いますが、実際に入力することはほとんどありません。コンパイラは、最後のトークンが文の終わりになりうる行の末尾にセミコロンを挿入します。識別子、リテラル、)}、そして return などいくつかのキーワードがそれにあたります。このルールがあるので、他の言語でよく見る次の書き方は失敗します。

func main()
{
	fmt.Println("Hello, World!")
}
./main.go:6:1: syntax error: unexpected semicolon or newline before {

func main() の後にセミコロンが挿入されたので、次の行の { がエラーになります。開き波かっこは必ず同じ行に書きます。ifforswitch などすべてのブロックで同じルールが当てはまります。

最初のエラーを解説する

初心者が最初の1時間で目にするメッセージを、Go 1.24が表示するとおりに載せます。

使っていないインポートや変数。

package main

import (
	"fmt"
	"os"
)

func main() {
	x := 5
	fmt.Println("hi")
}
./main.go:5:2: "os" imported and not used
./main.go:9:2: declared and not used: x

どちらも警告ではなくコンパイルエラーです。インポートか変数を削除してください。デバッグ中に変数を残しておきたい場合は、ブランク識別子に代入します:_ = x

関数名が小文字。

./main.go:6:6: undefined: fmt.println

公開されていない名前はパッケージの外からは見えません。fmt.Println を使います。

パッケージ名が違う。

package example.com/hello is not a main package

ファイルに package hello(または main 以外の名前)と書いてあるのに実行しようとしました。package main に変更します。

モジュールがない。

go: go.mod file not found in current directory or any parent directory; see 'go help modules'

go buildgo run . はモジュール単位で動きます。フォルダで一度 go mod init example.com/hello を実行してください。ファイル名を指定する go run main.go はモジュールがなくても動きます。

フォーマット

Goには公式のコードスタイルが1つあり、gofmt がそれを適用します。書いたファイルにはすべて実行しましょう。

go fmt ./...

インデントにはタブを使い、コメントや構造体のフィールドをそろえ、空白を正規化します。Goをサポートしているエディタは保存時に実行してくれます。Goのコードはどこでも同じ見た目になるので、設定することも、コードレビューで議論することもありません。

よくある質問

GoでHello Worldはどう書きますか?

これを main.go として保存します。

package main

import "fmt"

func main() {
	fmt.Println("Hello, World!")
}

そして go run main.go を実行すると、Hello, World! と表示されます。

なぜGoのプログラムには package main が必要なのですか?

package main は、このパッケージがライブラリではなく実行可能なプログラムであることをコンパイラに伝えます。プログラムは main パッケージの main 関数から始まります。それ以外のパッケージ名だとライブラリになり、go run は「is not a main package」と言って実行を拒否します。

なぜGoでは開き波かっこを同じ行に書くのですか?

Goは、文の終わりになりうる行の末尾に自動でセミコロンを挿入します。func main() の後もその対象です。そのため次の行に { を書くと別のブロックの始まりになってしまい、コンパイラは syntax error: unexpected semicolon or newline before { を報告します。波かっこは同じ行に書く必要があります。

Goのfmtとは何ですか?

fmt は、書式付きの入出力を扱う標準ライブラリのパッケージです(名前は「format」の略です)。fmt.Println は引数の間に空白を入れ、最後に改行を付けて表示します。fmt.Printf は書式文字列を使って表示します。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める