2011-06 << 2011-07 >> 2011-08

2011-07-31 (日)

*[Golang] いろいろ

Goのコンパイラが吐き出すコードを少し眺めてみる.もう少し最適化頑張って欲しいなぁ.gccgoとかだとまた変わるんだろうけどGCが無いのが難点.

GoでCGIを書く(http/cgi)

いつのまにか,http/cgiが出来ていたので試しに使ってみる.ただCGIだとオーバーヘッド大きそうなので,http.ListenAndServeを使ってサーブレットとして動かすのが良さそう.

package main
import "fmt"
import "http/cgi"
func main() {
        var _,err = cgi.Request()
        if err != nil {
                fmt.Println("Please run as a CGI");
                return
        }

        q := req.FormValue("q")

        fmt.Printf("Content-Type: text/plain\n\n")
        fmt.Printf("hello, world! %s \n",q)
}

最初はこう書いてたのだけど.

package main
import "fmt"
import "http"
import "http/cgi"

func main() {

        cgi.Serve(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
                q := req.FormValue("q")

                w.Header().Set("Content-Type", "text/plain")
                fmt.Fprintf(w,"hello, world! q= %v \n",q)
        }))

}

ResponseWriterとRequestを受ける関数にしておくと,http.ListenAndServeで動かしたときとか,GAEでもそのまま使えるので,こっち使うべきですね.

JSON

標準で用意されてるjsonパッケージ使って簡単に扱えます.

が……

type User struct {
    id  int;
    name  string;
}
func (u *User) Name() string {return u.name}
func (u *User) Id() string {return u.id}

という良くある構造体をMarshal()してみたけど,空のオブジェクトとして扱われてしまった.

json.Marshalの説明をよく読むと,「Only exported fields will be encoded.」って.

もしかして,構造体のフィールドを外部に公開しないといけないんですか.

type User struct {
    Id_  int "id";
    Name_  string "name";
}
func (u *User) Name() string {return u.Name_}
func (u *User) Id() string {return u.Id_}
  • id,nameを Id,Nameにしてみた
  • 既にあるゲッターと名前が被ったので, Id_, Name_に
  • Jsonとして出力される名前をタグで指定

絶対に何かが違うと思うというか,間違っている気がして仕方がない.

JSONに使うオブジェクトは,ゲッターやセッターは用意せずにフィールドを直接公開しておくのが良いのか.

後でもう少し調べてみよう.

名前を大文字にする以外に,外部に公開する手段を用意して欲しいなぁ.

MySQL

GoでMySQL使うためのパッケージ色々あるけど,未完成っぽいものが多いなぁ.

https://github.com/Philio/GoMySQL

これが一番完成度高そう.ざっとソース読んだ感じ,必要な物がそろってる気がする.

MySQLとか手元に環境が無いので会社で試そう.

XXX declared and not used.

goのプログラムのデバッグ中に一時的に一部のコード消したりすると,「XXX declared and not used.」というエラーが発生して面倒なので,せめてデバッグ中だけでも使われない変数許容して欲しかったのだけどできないっぽい…….Goのソースを見たら,疑わしきは罰するという強い意志を感じたのであきらめる.

package main
import "fmt"

func main() {
        var p, e = 3.141593, 2.718282

        fmt.Printf("hello, world %v\n",e)
}

このコードからエラーを取り除くために

  • _ = p

と書いてみたら,左辺に変数が無いといわれてしまったので,

  • _, e = p, e

と書いてみたらコンパイルが通った.

しかし,もう一つ変数に触ってるのが何か嫌だったので,

  • p = p

これでも許してくれた.

他には,

  • switch p{}

もありかと思ったけど,今のGoのコンパイラだと余分なJMP命令がコード中に混入するのでよろしくない.

2011-06 << 2011-07 >> 2011-08