はじめに
最近久しぶりにGoを触ることになったので、復習を始めました。この記事ではプログラミングの第1歩である、「Hello,World!」を出力するプログラムを4つ紹介し、それぞれをとても易しく解説します。
では、始めていきます。
プログラム
1つ目(1番シンプル)
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello, World!")
}
コードの解説
これは1番基本的といえるプログラムです。
1,package main
は「このプログラムは『メインパッケージ』として動く」ということを表します。Goではこのパッケージが実行の始まりとなります。
2,import("fmt")
はフォーマット済みの入出力 を行う(形式を整える)ための標準ライブラリをimportすることを表します。例えば、文字列と整数は型が異なりますがfmt
内では%s
や%d
を用いることで入出力を適切な型に変換することができます。
3,func main()
は「このプログラムのエントリーポイント(入り口)」を表します。Goではmain関数が最初に動きます。
4,fmt.Println()
は「内容の出力」を表します。また、出力の後に改行をしてくれます。
2つ目(HTTP通信を使う)
//
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()
は出力を表します。
fmt.Println()とfmt.Printf()の違い
fmt.Println()の特徴
- 引数をそのまま出力する。
- 自動的にスペースで区切ってくれる。
- 改行(\n)を自動で付加する。
fmt.Printf()の特徴
- フォーマット指定子(%sや%dなど)を使って、出力の形式を細かく制御する。
- 自動で改行しないので、必要なら明示的に「\n」を付ける。
- より柔軟でカスタマイズ可能。
以上から、「文字列に変数を埋め込んだり、特定の形式でデータを整形して出力したい場合」によく用いられる。
これから紹介する2つのプログラムは「Hello,World!」を出力するという目的で用いるのは望ましくないですが、今回は色々なものに触れるという名目なのでご了承ください。
それらが本来用いられる場面については適宜解説します。
3つ目(Muxを使う)
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
とは、「マルチプレクサ」のことであり、簡単に説明すると「複数の信号の入力を1つの信号にして出力するもの」です。このコードでは、http.ServeMux
というGoの標準ライブラリに含まれたものを利用しています。ちなみに、標準ライブラリに含まれないもので有名なものとしてはgorilla/mux
があります。
1,mux := http.NewServeMux()
は「新たにデータをネットワーク上で届ける際の案内役」をつくることを表します。
2,mux.HandleFunc("/", helloHandler)
はマルチプレクサに対して「ルール」を定義しています。この場合、「ブラウザから/
にアクセスが来たら、helloHandler
関数を実行する」ことを表します。
ローカルで立ち上げたWebサーバーはURL部分にhttp://127.0.0.1:8080/
を入力することで出力を確認できるので、/
へのアクセスはページを訪れる度に行われ、「Hello,World!」が出力されるという仕組みです。
Mux
の定義を思い出してもらえるとわかりやすいですが、本来Mux
は、複数のURLパスを扱う(複数のページ画面を必要とする)場合や複雑なリクエスト構造をもつ場合などに使われるものなので、単に「Hello,World!」を出力するプログラムで用いるのは不向きとなります。
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つのかたまりにしたもの」です。例えば、人のデータを扱う際、関連データとして年齢や性別、身長、体重などがありますが、これらの情報をまとめたものを「構造体」呼ぶということです。
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
メソッドを呼び出してメッセージの出力を行っています。
先ほどのMux
を用いた場合と同じように、構造体の定義を思い出してもらうとこのような単純なプログラムに構造体を用いるのはあまり適切でないです。本来であれば構造体はいくつかの状態をもつ複雑な処理を扱う場合などに用いられます。
おわりに
いかがでしたか?文中でも紹介したように、それぞれの書き方にはそれぞれの良さがあるのでそれぞれについて理解を深め、適切に用いられるよう、お互い頑張りましょう。
では、今回の記事はこれで終わりです。最後までお読みいただきありがとうございました。