ハックツハッカソン~メガマウスカップ~に参加しました。 普段はフロント園児なのですが、まさかのバックエンド担当になりGoを書くことになったので、期間中に勉強した内容をここに垂れ流します。
Goとは
- Googleが開発したプログラミング言語(Google内の課題を解決するために開発されたそう)
- 強力でシンプルな言語設計、複数のプログラムを同時に実行する”並行プログラミング”が特徴
変数
ゼロ値があり、初期化しなくても利用できる
- 数値型(int, float64など)は「0」
- 文字型(string)は「””」
- boolは「false」
- errorは「nil」
定数
型を明示しない場合、定数はデフォルトの型を持つ
- 整数(100)はint
- 浮動小数点(1.5)はfloat64
- 複素数(1+4i)はcomplex128
- ルーン(’A’,’朝’)はrune
- 文字列(”niki”)はstring
- 真偽値(ture)はbool
代入演算
Goの特徴
- Goはコンパイル時の後ろの改行を見て、自動でセミコロンを付与している
// OK
if a == 0{
}
// NG
if a == 0 // 0の後に;を付与するので、謎の{}が残る
{
}
- 繰り返しはforしか存在しない(=if文がない)
// 初期値; 継続条件; 更新文
for i:=0; i<=100; i=i+1{
}
// 継続条件のみ(while的な役割)
for i<=100 {
}
// 無限ループ
for {
}
// rangeを使った繰り返し
for i, v:=range[] int{1,2,3}{
}
テスト書くとき
- xxx_test.goのような名前のファイルにする
- テスト関数はTestという単語で始める
- テスト関数は1つの引数のみをとる。 t *testing.T
- *testing.T 型を使うには、他のファイルの fmt と同じように import "testing" が必要
- * testing.Tタイプのtがテストフレームワークへのhook
🐇 usage
// hello.go
package main
import "fmt" // Println関数を含むパッケージをインポート
// Hello関数を定義
func Hello() string {
return "Hello, world"
}
// main関数を定義
func main() {
fmt.Println(Hello())
}
// hello_test.go
package main
import "testing"
func TestHello(t *testing.T) {
got := Hello()
want := "Hello world"
if got != want {
t.Errorf("got %q want %q", got, want)
}
}
❯ go test
PASS
ok hello/src 0.002s
// 失敗するとこんな感じ
❯ go test
--- FAIL: TestHello (0.00s)
hello_test.go:10: got "Hello, world" want "Hello! world"
FAIL
exit status 1
FAIL hello/src 0.005s
naked return
戻り値に名前をつけると、return ステートメントに何も書かずに戻すことができる
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
fmt.Println(split(17))
}
- naked returnステートメントは、短い関数でのみ利用すべき
- 長い関数で使うと読みやすさに悪影響がある
Defer
defer へ渡した関数の実行を、呼び出し元の関数の終わり(returnする)まで遅延させるもの。
package main
import "fmt"
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
// hello
// world と返ってくる
defer へ渡した関数が複数ある場合、その呼び出しはスタックされる。スタック後は、後ろから取り出される(LIFO(last-in-first-out))
雑多メモ
- 型を後ろに書く(気持ち悪い)→ 日本語みたいな感じだと思えば許せるし、人間的には左から右へ文章を読むのでやさしい
- 2つ以上の引数が同じ型である場合には、最後の型を残して省略できる → うれしい
package main
import "fmt"
// 関数名(入力値とその型)(戻り値の型)
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b)
}