今回は、encoding/jsonパッケージのMarshal()から読み始めました。
それまでに、前回のExampleの事を復習していたら、godocコマンドのハックに…。
(ですが、本題と違ったのでまた違う日にやることにしました)
色々出てきたのでメモ。
引数の型がinterface{}になる時は、「何でもOK」という意味。(他の言語で言う、Object、object、void *、variant…など。)
deferキーワード。呼び出した関数が終了した後に呼び出される、後処理用スタックに積む。(その場で処理は実行されないので、ファイルのクローズなどをまとめておくと良い。)
recover()はdeferキーワードを使って呼び出した関数内でしか利用できないので注意。
reflect.Valueは、今日は読まないが、「ポインタを持った構造体」
reflect.ValueOf()はポインタを持った構造体を返す関数ということにしておく。
読んだ所は、encoding/json#Marshalを掘り下げる感じで。
- encoding/json#Marshal
- e = &encodeState{}
- e.marshal()
- エラーチェック用defer関数を登録して、e.reflectValue()
- reflectValueQuoted(v, false)で呼び出す。(1.1.2だと267行目付近)
- IsValid()かどうかをチェック
- Marshalerインターフェイスを実装しているかどうかをチェック(TypeAssertionを使って、変換する)
- Marshalerインターフェイスではない場合、ポインタをもらっているという想定で、v.Addr().Interface().(Marshaler)で参照先の値を取り出してTypeAssertionする。
- TypeAssertionは変換できない場合もあるので、代入用変数と、チェック用の変数を2つ左辺に記述する形で使う。(i, ok := v.(int)…など)チェック用変数がfalseの場合は変換できなかった事を示す。(interfaceを実装していない、型が違うなど。)
- MarshalJSON()([]byte, error)を実装していれば、自分で実装したJSONエンコード処理が呼ばれる。
- それ以外は、reflect.Kind()で型の種類を取得して、それぞれの方法で出力する。
- 構造体はフィールドごとに再起呼び出し。
- fallthroughキーワードは次のcaseを実行する。
- Goのswitchはデフォルトbreak!
- reflect.Kind()はhttp://goo.gl/uDQOPOのconst値を返してくる。
- invalid、unsafePointer、channel、func、Mapのキーがstring以外のものは、変換できずerrorを返す。
それから、私が作成したサンプルコードとテストコードをまとめてgithubに置きました。
https://github.com/tyokoyama/golangcafe
次からはこのリポジトリにまとめてCommitしていくことにします。
(忘れてなかったら、各回ごとにbranchも作っておくようにします。)
次回は、goroutine & channels関連をやってみる予定です。
0 件のコメント:
コメントを投稿