【初めてのGO言語】初学者がローカル環境を構築して、Hello Worldをブラウザに表示させる流れ

# はじめに
## 概要
go言語初学者の人向けの記事です。環境構築した後にどうすればいいかわからない、動的言語（rubyやphp）しか経験したことがない、といった方の最初のステップとして、お役に立てると思います。

この記事ではディレクトリやファイルを作るところから始めて、ブラウザに「Hello World!」を表示するところまで行います。
## 目的
- ginなどのパッケージを用いずに、自力でローカルサーバを立ち上げる方法を理解すること


# 事前準備

## ディレクトリとファイルの準備をしよう
まずは、今回作業するディレクトリとファイルを準備しましょう。まずはディレクトから作成します。

### ディレクトリをmkdirコマンドで作成しましょう
以下のコマンドで指定の場所に新しいフォルダを作りましょう。

```bash:ターミナル
% mkdir hello_world
```
ここではhello_world名前のフォルダを作ります。

### cdコマンドでディレクトリを移動しましょう
先ほど作成したディレクトリに移動しましょう。

```bash:ターミナル
% cd hello_world
```

### touchコマンドでファイルを作成しましょう
以下のようにファイルを作成します。

```bash:ターミナル
% touch main.go
```
このmain.goがこれから作業していくファイルです。

### ディレクトリ構造を確認しましょう
以下のようなディレクトリ構造になっていれば成功です。

```bash
hello_world
├── main.go

```

## packageの記述をしよう
### <font color="Red">package</font>
package(パッケージ)とは、機能を分ける仕組みのことです。packageとして宣言することで、名前空間としての機能を果たします。


### packageを指定しましょう
以下のように、main.goを記述しましょう。

```go:go.main
package main
```
main.goファイルに記述された内容を使用したいので、上記のような記述をします。

今回使用するファイルはmain.goファイルのみなので、それ以外の機能（ファイル）のことは考えなくて大丈夫です。

## importの記述をしよう
packageの指定の後は、importするpackageを記述します。packageをimportすることで、外部で開発された機能を自分の開発環境でも取り入れることができます。
### <font color="Red">import<font>
importの記述をすることで、goが標準で用意してくれているpackageを開発中のアプリケーションで使用できるようになります。

### packageをimportしましょう
以下のように記述し、必要なpacakageをimportしましょう。

```go[]:main.go
package main

import (
	"net/http"
)
```

### <font color="Red">net/http</font>
net/httpはgoが標準で用意してくれているHTTPを扱うpackageです。net/httpをimportすることで、HTTPクライアントとHTTPサーバーを実装するために必要な機能を使用することができます。

<br>
これで必要な準備は整いました。これからローカル環境を構築します。

# ローカル環境の構築
それではこれから、順々にソースコードを記述し、ローカル環境を構築していきましょう。環境を構築すると聞くと、なにやら難しそうに聞こえますが、記述するコードは２行で済みます。これは先ほどimportしたpackageの恩恵に与れてることを表しています。

しかし、１行１行重要なので、じっくり理解しながら進めていきましょう。

## 静的ファイルを用意しよう
### 静的ファイルを配置するディレクトリ作成しましょう
以下のようにディレクトリを作成してください。
この時実行するディレクトリはhello_worldです

```bash:ターミナル
% mkdir templates
```
### 静的ファイルを作成しましょう
以下のようにコマンドを実行しましょう
この時も、実行するディレクトリはhello_worldです。

```bash
% touch templates/index.html
```
### ディレクトリ構造を確認しましょう
以下のようなディレクトリ構造になっていれば成功です。

```bash
hello_world
├── main.go
└── templates
    └── index.html
```

### main.goに関数を定義しましょう
これから処理を記述する関数を定義します。今回はpackageでmainと指定してますので、main関数を定義しましょう。

```go
package main

import (
	"net/http"
)

func main() {

}
```
goでは今回記述したmain関数がどの関数よりも先に読み込まれます。万が一このpackageに定義した関数（今回であればmain関数）がなければ、コンパイル時にエラーが起きてしまいます。したがって、packageに指定した名前の関数は必ず記述するということを認識しましょう。

### index.htmlを以下のように記述しましょう

```html:templates/index.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <title>Sample App</title>
</head>

<body>
  <h1>Hello World!!!</h1>
</body>

</html>

```

## 静的ファイルを配置したディレクトリを指定しよう
先ほど記述したファイルをmain.goで指定します。

### 作成したファイルを指定しましょう
main.goを以下のように記述しましょう。

```main.go
package main

import (
	"net/http"
)

func main() {
	http.Handle("/", http.FileServer(http.Dir("templates")))

}
```
記述したコードにより、どのファイルのHTMLを表示させるかを決定することができました。今回であれば、"/"にアクセスする際には、templatesディレクトリに位置するhtmlファイルが呼び出されるように設定することができました。

<br>
今回出てきた関数をそれぞれ確認しましょう。
### <font color="Red">http.Handle()</font>
**http.Handleとは、URLをに対応するhttp.HandlerをDefaultServerMuxに登録する関数です。**
http.handlerはHTTPリクエストを受けてレスポンスを返すインターフェースのことで、DefaultServerMuxとは、デフォルトで用意されている要求されたURLを元にどのページを表示するか判断してくれる関数のことです。

つまり、このhttp.Handleを用いることで、指定のURLに遷移させることが可能となるということです。

### <font color="Red">http.FileServer(http.Dir("呼び出したいディレクトリ"))</font>
http.Dirとhttp.FileServerを用いることで、ルートディレクトリを指定することができる。

## ポートを指定しましょう
呼び出すファイルを指定した後は、ポートを指定しましょう。main.goを以下のように記述しましょう。

```main.go
package main

import (
	"net/http"
)

func main() {
	http.Handle("/", http.FileServer(http.Dir("templates")))
	http.ListenAndServe(":8080", nil)
}
```
今回の記述でポートの8080を開くことができました。

### <font color="Red">http.ListenAndServe()</font>
http.LinstenAndServerとは、引数にポート番号とハンドラを渡すことで、指定したポートを開くことができる関数です。ハンドラにnilが渡されることで、DefaultServerMuxのハンドラが使用される。特に何か追加実装する場合でなければ、第二引数はnilを渡すと覚えておけば良い。

### ブラウザの表示を確かめよう

<img width="761" alt="スクリーンショット 2020-04-11 16.49.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452544/854b7346-7509-95e0-5fd3-cb5a94997925.png">

上記のような表示になっていれば成功です。お疲れ様でした。
## この記事の振り返り