2013年6月23日日曜日

datastore の要素名は大文字で始める

GAE + Go ではデータを保存するために datastore というデータベースが使われます。

Storing Data - Google App Engine
https://developers.google.com/appengine/docs/go/datastore/

datastore では構造体やマップを保存することができます。
このとき構造体のメンバ名は必ず大文字で始めなければいけません。
import (
    "appengine"
    "appengine/datastore"
)

// 小文字で要素名が始まっているので保存されない
type Entity struct {
    name string
    value string
}

/*
// 大文字で始めると保存される
type Entity struct {
    Name string
    Value string
}
*/

func save(w http.ResponseWriter, r *http.Request) {
    entity := new(Entity)
    entity.name = "hoge"
    entity.value = "piyo"
    /*
    entity.Name = "hoge"
    entity.Value = "piyo"
    */
    
    c := appengine.NewContext(r)
    key := datastore.IncompleteKey(c, "Entity", nil)
    _, err := datastore.Put(c, key, entity)
    if err != nil {
        c.Errorf(err.Error())
    }
}

小文字で始めた場合、datastore には空のデータが保存されます。
実際に中身を確認してみると name や value が保存されていないことがわかります。
(ID や Key Name はデータとは関係なく自動で作成されます。)



なぜなら Go では変数名の最初が大文字か小文字かによって意味が異なるためです。
大文字の変数はパッケージ外に公開され、小文字の変数は公開されません。
つまりパッケージ内だけで使いたい変数は小文字ではじめ、
パッケージ外から参照される変数は大文字で始めます。
クラス名を大文字で、インスタンス名を小文字で始めるような習慣と混ざってちょっとわかりづらい気もしますが・・・。

構造体の要素名は datastore パッケージから参照されるため大文字で始めます。
小文字で始まっているものは datastore パッケージからは見えていません。
つまり上のコードの Entity は空の構造体であるとみなされます。
// 中からは name や value が見える
type Entity struct {
    name string
    value string
}

// 外からは空に見える
type Entity struct {
}

よって、空のデータが保存されます。
エラーにはならないため、これを知らないと詰まります。

他にも Go のパッケージでは変数名を大文字で始めることを要求するものが多いので注意が必要です。

0 件のコメント:

コメントを投稿