『恥ずかしい勉強会』とは
「今さら聞くのも恥ずかしいし勉強し始めるにも何から始めればいいか分からない人々が寄り添って1ミリだけ前進する」というコンセプトの勉強会です。 ノーマサカリ!「ググレカス」禁止!
建物にはたどり着いたけど、建物内で迷子になりました(恥ずかしい…)
お品書き
- Go言語とは
- Go言語のインストール
- Hello, 世界!
- 自作パッケージの開発・置き方 // ここをバッチリ聞きたい
- GitHubを使った自作パッケージの公開
- (時間が余りまくったら)自作HTTPサーバを書く
資料
https://gist.github.com/otiai10/c2a1cfefdfb7f5798865a30d12ade4c1
学んだこと
Go言語のインストール
わたしはGoのバージョン管理ツールgvmを利用しているので、以下のコマンドでインストールする。
$ gvm install go1.8
$ gvm use go1.8 --default
GOPATHの設定が重要。$GOPATH/src
以下にすべてのパッケージが格納されるため。go get
コマンドでパッケージを取得することができる。
GOROOTについては、現在では設定する必要はない。
gvmを使わない場合は、以下のを参考にシェルの設定に書いておくとよい。
export GOPATH=$HOME/go
export PATH="$GOPATH/bin:$PATH"
go env
コマンドでgoの環境変数を確認する。下記のようになっているはず。
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/mom0tomo/.gvm/pkgsets/go1.8/global"
GORACE=""
GOROOT="/Users/mom0tomo/.gvm/gos/go1.8"
GOTOOLDIR="/Users/mom0tomo/.gvm/gos/go1.8/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/kh/6_bmx1pn6rggyfv6c3l2r6ch0000gp/T/go-build863603804=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
Hello, 世界!
※GoではHello, World
ではなくHello, 世界
!
GoはUnicodeに対応しているため、漢字も使える。Hello, عالم
とかも行ける。
package main // Goを実行するにはmainパッケージが必須
import "fmt" // 標準パッケージのfmt(フォーマットするやつ)をインポートする
func main() { // main関数も必須
fmt.Println("Hello, 世界!")
}
実行する。
$ go run main.go
Hello, 世界!
Goの基本的な書き方
main.go
package main
import (// 複数パッケージをインポートするときは()でくくる
"fmt" // Goの標準・準標準パッケージは上にまとめて書く
"net/http"
"github.com/mom0tomo/fizzbuzz" // OSSのパッケージは下にまとめて書く
)
func main() {
fmt.Println("hogehoge")
// インポートしたのに使っていないパッケージがあるとコンパイル時に怒られる
}
GoでFizzBuzz
Goにはwhile文がない。for文はある。 if文はネストが深くなりがちなので、switch文を使うことが多い。
package main
import "fmt"
func GetOutput(i int) string {
fizz := i % 3 // :=は代入変数。そして関数宣言と型宣言の役割をしてる
buzz := i % 5
switch {
case fizz == 0 && buzz == 0: // case文に式を書ける!
return "FizzBuzz" // breakしなくても自動でbreakしてくれる
case fizz == 0:
return "Fizz"
case buzz == 0:
return "Buzz"
default:
return fmt.Sprintf("%v", i)
// はじめに「S」をつけることで出力ではなくフォーマットした結果を文字列で返す。変数に代入する際などはこちらを使う
}
}
func main() {
for i := 0; i < 20; i++ {
output := GetOutput(i)
fmt.Println(output)
}
}
go run してみる。
$ go run main.go
FizzBuzz
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
FizzBuzz
16
17
fizz
19
自作パッケージをつくる
mainパッケージに全て書いてしまっていたので、GetOutputメソッドを切り出してfizzbuzzパッケージとする。
$GOPATH/src
配下にパッケージつくることで、標準パッケージのようにインポートして使うことができる。
$ cd $GOPATH/src
$ mkdir fizzbuzz
$ touch fizzbuzz/fizzbuzz.go
$ ls -la
drwxr-xr-x 3 mom0tomo staff 102 6 8 21:08 fizzbuzz
drwxr-xr-x 21 mom0tomo staff 714 6 8 20:27 github.com
drwxr-xr-x 3 mom0tomo staff 102 4 3 20:54 golang.org
$GOAPTH/src/fizzbuzz.go
package fizzbuzz
import "fmt"
func GetOutput(i int) string {
fizz := i % 3
buzz := i % 5
switch {
case fizz == 0 && buzz == 0:
return "FizzBuzz"
case fizz == 0:
return "Fizz"
case buzz == 0:
return "Buzz"
default:
return fmt.Sprintf("%v", i)
}
}
main.go
package main
import (
"fmt"
"fizzbuzz" // 標準パッケージのようにインポートできる
)
func main() {
for i := 0; i < 20; i++ {
output := fizzbuzz.GetOutput(i)
fmt.Println(output)
}
}
GitHubを使った自作パッケージの公開
githubに公開してみる。
標準パッケージのような形式でインポートして開発してきたが、ここでgithubに公開したパッケージを使うことにする。
import部分の記述を以下のように変更する。
package main
import (
"fmt"
"github.com/{user name}/fizzbuzz" // githubに置いたパッケージを利用する
)
func main() {
for i := 0; i < 20; i++ {
output := fizzbuzz.GetOutput(i)
fmt.Println(output)
}
}
この状態で実行すると、以下のようなエラーが出る。
cannot find package "github.com/{user name}/fizzbuzz"
これは$GOPATH/src配下にインポートしようとしているパッケージがない、というエラー。
エラーを解消するために、go get
というコマンドでパッケージを取得する。
$ go get gihub.com/{user name}/fizzbuzz
ここでgo run
して、パッケージを分割する前と同じ結果になることを確認する。
$ go run main.go
FizzBuzz
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
FizzBuzz
16
17
fizz
19
OK!
いろいろ試してみる
パッケージの名前と関数の名前を変えてみる
fizzbuzz.go
package test // fizzbuzzじゃないのにしてみる
...
-> 動く!
main.goの名前を変えてみる
-> mom0tomo.goとかでにしても動く!