Go 勉強中

いまさらGo 勉強中。なかなか、いい。好みだ。言語仕様がリッチじゃないところが好き。コンパイラの質が上がれば、システム用言語として本当に使えるんじゃないだろうか。
感覚としてはCとPythonの間って感じ。Pythonと違って型があるので、コンパイル時のエラーチェックが期待できる。その割にほとんどの型宣言を省略できるので、書くのも楽だ。センスいいなあ。
ライブラリもかなりそろってる。 ここをみると、普通に必要そうなものはだいたいある感じ。AST(Abstract Syntax Tree) とかELFパーザとか、普通に必要なさそうなものまである(-_-)。パッケージの名前付けが、Javaっぽいので、どこに何があるかがなんとなくわかるのがうれしい。

エコーサーバー

ネットワークまわりはどんなものかと、エコーサーバを書いてみた。コードの意味は自明だと思う。変数の型宣言を一つもしてないところに注目。

package main
import "net"
import "io"

func main() {
    addr := net.TCPAddr{net.ParseIP("0.0.0.0"), 3000}
    listner, _ := net.ListenTCP("tcp4", &addr)
    for {
        con, _ := listner.AcceptTCP()
        go io.Copy(con, con)
    }
}

面白いのは、下から3行目の「go」。これがgoroutineというやつで、コンカレントに動くプログラムが簡単にかける。ここでは複数のクライアントを並行して捌くために使っている。こんなに簡単に書けるのは感動的だ。

もう一つ面白いのは

   io.Copy(con, con)

con は net.TCPConn 型。一方 io.Copyは次のようにio.Writerとio.Reader を引数に取る関数である。

func Copy(dst Writer, src Reader) (written int64, err os.Error)

Writer型、Reader型は、それぞれ 「Read/ Writeという関数が定義されている型」として定義されている。

type Reader interface {
    Read(p []byte) (n int, err os.Error)
}
type Writer interface {
    Write(p []byte) (n int, err os.Error)
}

net.TCPConnにはこの二つの関数が定義されているので、WriterでありReaderでもあるということになるわけだ。いわゆるダックタイピングなのだが、PythonRubyのそれと違って、ちゃんと型がinterfaceとして定義されているので、型チェックが効く。

goにはobjectはなくstruct だけ。structなので複合リテラルとして初期化できる。この部分は括弧が「()」でなく「{}」 になってることからもわかるように、関数呼び出しではなく複合リテラルだ。

net.TCPAddr{net.ParseIP("0.0.0.0"), 3000}

性能

今のところ、残念ながら性能はそれほどにはよくないようだ。フィボナッチで評価されるのは不本意だろうけど、フィボナッチで計ると、gcc 最適化なしよりは速い、という程度。gcc -O3 よりも3倍、java よりも2倍近く遅い。っていうかJava速いな。。。これほどとは。でもこの辺はガンガン最適化されてすぐにCと同程度になるんじゃないだろうか。

所感

ライブラリの整い具合をみても、すでに使える状態になってる感じ。是非使っていきたい。あとはIDEが出ればな。。。あと、言語の名前、もう少しなんとかならなかったのか。golangと書くしかないのか。。。