【Go初学者向け】４つの「Hello,World!」から学ぶGo

# はじめに
最近久しぶりにGoを触ることになったので、復習を始めました。この記事ではプログラミングの第１歩である、「Hello,World!」を出力するプログラムを４つ紹介し、それぞれをとても易しく解説します。
では、始めていきます。

# プログラム
### １つ目（１番シンプル）
```go:hello_1.go
package main

import (
	"fmt"
)

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

```
#### コードの解説
これは１番基本的といえるプログラムです。

1,`package main`は「このプログラムは『メインパッケージ』として動く」ということを表します。Goではこのパッケージが実行の始まりとなります。

2,`import("fmt")`はフォーマット済みの入出力 を行う（形式を整える）ための標準ライブラリをimportすることを表します。例えば、文字列と整数は型が異なりますが`fmt`内では`%s`や`%d`を用いることで入出力を適切な型に変換することができます。

`3,func main()`は「このプログラムのエントリーポイント（入り口）」を表します。Goではmain関数が最初に動きます。

4,`fmt.Println()`は「内容の出力」を表します。また、出力の後に改行をしてくれます。

### ２つ目（HTTP通信を使う）
```go:hello_2.go
// 
package main

import (
	"fmt"
	"net/http" 
)

func main() {
	http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, World!")
	}))
}
```
#### コードの解説
これはHTTP通信を用いたプログラムです。`HTTP通信`を簡単に説明すると「ウェブページを表示する通信」です。

1,`import("net/http")`はそのHTTP通信を行うための標準ライブラリをimportすることを表します。

`2,http.ListenAndServe(":8080", ...)`は「8080番ポートでウェブサーバーを始める」ということを表します。なお、「8080」というのはよく使われるというだけで、何か特別な意味があるというわけではありません。

3,`http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {...})`は「リクエスト（ブラウザからのアクセス）が来たときに動く処理」を表します。その中で、`w http.ResponseWriter`は`w（write：書き込み）`を利用して返す（表示する）データを書き込んでブラウザに送ることを表し、

4,`r *http.Request`は`r（read：書き込み）`を利用してリクエスト（送られてきた情報）を読み込むことを表します。

5,`fmt.Fprintf()`は出力を表します。

:::note info
fmt.Println()とfmt.Printf()の違い
**fmt.Println()の特徴**
<ol>
<li>引数をそのまま出力する。
<li>自動的にスペースで区切ってくれる。
<li>改行（\n）を自動で付加する。
</ol>
以上から、「シンプルなデバッグ出力や、特にフォーマット指定が不要な場合」によく用いられる。

**fmt.Printf()の特徴**
<ol>
<li>フォーマット指定子（%sや%dなど）を使って、出力の形式を細かく制御する。
<li>自動で改行しないので、必要なら明示的に「\n」を付ける。
<li>より柔軟でカスタマイズ可能。
</ol>

以上から、「文字列に変数を埋め込んだり、特定の形式でデータを整形して出力したい場合」によく用いられる。
:::

:::note warn
これから紹介する２つのプログラムは「Hello,World!」を出力するという目的で用いるのは望ましくないですが、今回は色々なものに触れるという名目なのでご了承ください。
それらが本来用いられる場面については適宜解説します。
:::

### ３つ目（Muxを使う）
```go:hello_3.go
package main

import (
	"fmt"
	"net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, World!")
}

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", helloHandler)
	http.ListenAndServe(":8080", mux) 
}
```

#### コードの解説
これはMuxを用いたプログラムです。`Mux`とは、「マルチプレクサ」のことであり、簡単に説明すると「複数の信号の入力を１つの信号にして出力するもの」です。このコードでは、`http.ServeMux`というGoの標準ライブラリに含まれたものを利用しています。ちなみに、標準ライブラリに含まれないもので有名なものとしては`gorilla/mux`があります。

1,`mux := http.NewServeMux()`は「新たにデータをネットワーク上で届ける際の案内役」をつくることを表します。

2,`mux.HandleFunc("/", helloHandler)`はマルチプレクサに対して「ルール」を定義しています。この場合、「ブラウザから`/`にアクセスが来たら、`helloHandler`関数を実行する」ことを表します。
ローカルで立ち上げたWebサーバーはURL部分に`http://127.0.0.1:8080/`を入力することで出力を確認できるので、`/`へのアクセスはページを訪れる度に行われ、「Hello,World!」が出力されるという仕組みです。

:::note info
`Mux`の定義を思い出してもらえるとわかりやすいですが、本来`Mux`は、**複数のURLパスを扱う（複数のページ画面を必要とする）場合や複雑なリクエスト構造をもつ場合**などに使われるものなので、単に「Hello,World!」を出力するプログラムで用いるのは不向きとなります。
:::


```go:hello_4.go
package main

import "fmt"

type Message struct {
	Text string
}

func (m Message) Print() {
	fmt.Println(m.Text)
}

func main() {
	msg := Message{Text: "Hello, World!"}

	msg.Print()
}
```

#### コードの解説
これは構造体を用いたプログラムです。構造体とは簡単にいうと「いろいろな種類の互いに関連するデータをまとめて， １つのかたまりにしたもの」です。例えば、人のデータを扱う際、関連データとして年齢や性別、身長、体重などがありますが、これらの情報をまとめたものを「構造体」呼ぶということです。

1,`type Message struct {...}`は構造体の定義をしています。今回の場合、この構造体は`Text`というstring型（文字型）をもつということを表します。

2,`func (m Message) Print() {fmt.Println(m.Text)}`は、Message構造体のメソッド（Print）を定義していることを表します。
今回は適当に`m`というインスタンスを用意しました。そして、`fmt.Println`を使って構造体に格納されたメッセージ（`m.Text`）を出力します。

3,`msg := Message{Text: "Hello, World!"}`は「構造体のインスタンス化」を表します。具体的には、`Message`のインスタンスを作成し、`Text`フィールドに「Hello, World!」を格納しています。

4,`msg.Print()`は3,で作成したインスタンスの`Print`メソッドを呼び出してメッセージの出力を行っています。

:::note info
先ほどの`Mux`を用いた場合と同じように、構造体の定義を思い出してもらうとこのような単純なプログラムに構造体を用いるのはあまり適切でないです。本来であれば構造体は**いくつかの状態をもつ複雑な処理を扱う場合**などに用いられます。
:::

# おわりに
いかがでしたか？文中でも紹介したように、それぞれの書き方にはそれぞれの良さがあるのでそれぞれについて理解を深め、適切に用いられるよう、お互い頑張りましょう。
では、今回の記事はこれで終わりです。最後までお読みいただきありがとうございました。