初めてのGo言語(golang)
突然新言語を書きたくなってGoを調べてみました。
Goってどんな言語?
Googleが開発した言語で2009年に登場しました。
公式サイトはThe Go Programming Languageです。
チュートリアルには日本語も用意されているので英語が苦手な方でもすぐに着手できます。
コンパイル型の言語だそうです。パラダイムはよくわからず...。
Goを書き始める
インストール
Macの方はHomebrewで一発です。
$ brew install go $ go version go version go1.3 darwin/amd64
そのほかのOSやMacだけどHomebrewを使わない、といった方はこちらを参照してください。
Hello World
Test.goファイルを以下の内容で作成してgoコマンドで実行します。
package main import "fmt" func main() { fmt.Printf("hello, world\n") }
$ go run Test.go hello, world
できました。
チュートリアルをひと通りやってみる
チュートリアルはこちらです。
目に止まった特徴的だと感じたものを書き残しておきます。
Multiple results
タプル、と呼ばれたりするものですね。今どきの言語っぽいです。
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) }
Named results
戻り値に変数名をつけて関数内ではreturnを書くだけで良いようです。
関数が長くなるとわかりづらくなりそうな気が...。
package main import "fmt" func split(sum int) (x, y int) { x = sum * 4 / 9 y = sum - x return } func main() { fmt.Println(split(17)) }
Short variable declarations
関数内で使える暗黙的な型宣言らしいです。
型推論が充実すればこの書き方をする必要がないような...。今のところメリットはよくわかってません。
package main import "fmt" func main() { k := 3 fmt.Println(k) }
Slicing slices
配列の中の値をスライスして取得できます。これはなかなか便利そう。
package main import "fmt" func main() { p := []int{2, 3, 5, 7, 11, 13} fmt.Println("p ==", p) fmt.Println("p[1:4] ==", p[1:4]) // missing low index implies 0 fmt.Println("p[:3] ==", p[:3]) // missing high index implies len(s) fmt.Println("p[4:] ==", p[4:]) }
Function values
今どきの言語っぽく関数はファーストクラスのようです。
package main import ( "fmt" "math" ) func main() { hypot := func(x, y float64) float64 { return math.Sqrt(x*x + y*y) } fmt.Println(hypot(3, 4)) }
Goroutines
goキーワードを使って軽量スレッド上で実行できるそうです。
簡単でなかなか良さそうですね。
package main import ( "fmt" "time" ) func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func main() { go say("world") say("hello") }
Channels
チャネル、という仕組みでスレッドの待ち合わせが簡単にできるみたいです。
package main import "fmt" func sum(a []int, c chan int) { sum := 0 for _, v := range a { sum += v } c <- sum // send sum to c } func main() { a := []int{7, 2, 8, -9, 4, 0} c := make(chan int) go sum(a[:len(a)/2], c) go sum(a[len(a)/2:], c) x, y := <-c, <-c // receive from c fmt.Println(x, y, x+y) }
所感
ささっとチュートリアルを見たぐらいなので、かなり浅い考察しかできていませんが今の思いを正直に書いていきます。
- 型推論がいまいちすぎる??
- ポインタ出てきた!?後発言語で見るのは逆に新鮮!
- Map、配列の宣言があんまりきれいじゃないような...
- 関数がファーストクラスだけど、それ以外に関数型らしさ(定数とか遅延評価的なもの)はほとんどない?
- クラスの仕組みがないのにびっくり!(structにメソッドを定義する)
- スレッドの扱いはかなり楽そう
- 売りはどこなんだろう??スレッド?
こんな感じで第一印象はいまいちです...。
(パラダイムなど下調べをほとんどせずに書いているのも良くないですね...)
ただ、もう少し深く見ていけばオブジェクト指向や関数型の考え方からは少し離れた設計技法があるなど実はかなり奥が深い言語だったりするのかな?といった期待もあります。
今後も少しずつ調べていこうと思います!