Go言語始めました
環境準備(Mac)
- 以下の公式サイトからGoのダウンロードを行う
https://go.dev/dl/ - インストール後に、Pathを通す必要あり。 nanoを起動してパスを記載。
$ sudo nano ~/.bashrc # 以下、~/.bashrcの内容 export GOPATH=$(go env GOPATH) export PATH=$PATH:$GOPATH/bin
- ~/.bashrcへの登録内容を環境に反映する。
$ source ~/.bashrc
- go install golang.org/x/tools/cmd/godoc@v0.1.10 「go get」はVer1.16で廃止されているため、パッケージのInstallは「go install」で行う。@の後ろでVersionを指定すること。
初歩
Hello World
以下の通りコーディングして実行する。
package main import "fmt" func init() { fmt.Println("init") } func bazz() { fmt.Println("Bazz") } func main() { bazz() fmt.Println("Hello world!") }
- 実行するには、main()が必要であること。
- init()は、最初に(mainよりも先に)呼び出されること。
- Publicメソッドは、冒頭大文字で始めるのが原則であること
- IDE「Go Land」では、文字列変数には「a....」というガイドが表示されること
- コメントは、「//」でインラインコメント、「/〜/」でブロックコメント。
- 実行ショートカットは、Macの場合、デフォルトは「Control+R」。Preferenceから変更可能。
パッケージのインポート
- importを複数行う場合は、import()で記載する
import ( "fmt" "os/user" "time" )
- 上記「os/user」のように、階層下がある場合は「/」で区切ること.
標準パッケージは、以下のサイトを参照する。
- メソッドの説明を確認する場合は上のドキュメントを参照するか、ターミナルから次のコマンドを実行する。
# go doc パッケージ名 メソッド名 $ go doc fmt Println package fmt // import "fmt" func Println(a ...any) (n int, err error) Println formats using the default formats for its operands and writes to standard output. Spaces are always added between operands and a newline is appended. It returns the number of bytes written and any write error encountered.
特徴的なポイント
宣言時のデータ型は、前ではなく後ろで行う(VBっぽい?)
// 関数宣言 func(param int) float64 { // : } // 変数宣言 var variable int // 変数宣言(配列) var ary []int
配列とスライス
要素数が予め固定なのを「配列」と呼び、要素数が動的なものを「スライス」と呼ぶ(ようです)
ファンクションは変数に代入できる(最近珍しくはない)
add := func(x int ,y int){ return x+y } result := add(3,5) fmt.Println(result) // -> 8
クロージャってなんじゃ?
昔から名前だけは聞いていたけど、出会ったことはなかったクロージャ。Static、というかPrivateメンバ変数を持ったクラスと理解したけど、ちょっと違いそう。そもそもGoにクラスがないことをここで知った。
func incrementGenerator() func() int { x := 0 return func() int { x++ return x } } func main() { counter := incrementGenerator() fmt.Println(counter()) // -> 1 fmt.Println(counter()) // -> 2 fmt.Println(counter()) // -> 3 fmt.Println(counter()) // -> 4 }
遅延処理を行う defer
ファンクション単位の最後に実行を行うDefer。
func main(){ defer fmt.Println("test1") fmt.Println("test2") fmt.Println("test3") fmt.Println("test4") } // -> test2 // -> test3 // -> test4 // -> test1 ← defer を書いた行がこちらが後に出る
主な用途としては、ファイルのOpen/Close処理。Try~Finallyみたいなイメージ?
func main(){ file, _ := os.Open("./test.go") defer file.Close() // <- 処理後にファイルクローズする行われる data := make([]byte ,100) file.Read(data) fmt.Println(string(data)) }
エラーハンドリング。
GoにはTry~Catch、Exceptionが存在しない。エラーは、ファンクションの戻り値として規定し、その値を単純にIFで比較する。
func main() { file, err := os.Open("./tsest.go") defer file.Close() // ↓ 単純に、err を Ifで判定。 if err != nil { log.Fatalln("Error!", err) } }
panicとrecover
panicはPGの強制終了。recoverはpanicで終了されることを防ぐもの。ただし、コード原則としてエラーは適切にハンドリングするべきであり、panicは作らないようにすべき。
func DBConnect() { // PG強制終了 panic("Unable to Connect Database!") } func save() { // deferのため、DBConnect()後に処理 defer func() { s := recover() // DBConnect()のPanicをキャッチ fmt.Println(s) }() DBConnect() } func main() { save() fmt.Println("OK?") }