どうも、初めまして。アットファイブの佐伯です。
最近、GO言語を扱う機会が多いので、今回から記事を書いていくにあたって、まず初めにGOの基本的な部分について振り返りも兼ねて、実際に作業をしていて嵌まった事やその際にどうやって解決できたかを備忘録的に書き残していきたいと思います。
※同じく本サイトにGOについての記事を書いている方もいるのでよければ見ていってください!
-フォーム画面とDBの連携でのお話
つい最近、WEBページでもよくある「フォーム画面」で入力した値をサーバーを介してデータベースへ登録し、
最後に完了ページで入力(DBの最新情報)を表示するといった仕組みを作っていたのですが、
ここで起きた事として、画面遷移しても何も映らない。。。
サーバー側のログを見ると確かに値はPOSTされていました。
順にPOSTされたデータがどこで落ちているのか調査。
DBとのデータのやり取りをする際ににGO言語の構造体(stract)を媒体に行っているので、まずはそこの確認です。
(※以下はサンプルコードです。)
[javascript collapse=”false” language=”style=”]
// 構造体を以下の3つの箱で定義
type Datas struct{
StartTime time.Duration `json:"starttime"`
EndTime time.Duration `json:"endtime"`
IntervalTime int `json:"intervaltime"`
}
// 上の構造体を変数へ
var datas Datas
// 入力画面
func postdata(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.ParseFiles("********.html"))
// template表示
t.Execute(t, nil)
}
// 結果出力画面
func getdata(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.ParseFiles("********.html"))
// POSTされたデータを受け取れるようにする
r.ParseForm()
// map[interfave]の定義
m := make(map[string]interface{})
// 上の構造体にデータを格納
data = json.Unmarshal(datas, m)
if data != nil {
return data
}
// 読み込んでいるテンプレートへデータを受け渡し
ct.Execute(w, data)
}
[/javascript]
ざっくりですが、POSTデータをアンマーシャルできるようにマップ型へ一度変換してあげて、
その後そのまま構造体へ入れる流れで組んでいたのですが、これだと先述した通りデータが構造体へ入っていかない。。。
色々調べてみるとどうやら構造体に入れるには、マップ型では直接構造体へはでは変換できず
[]byte型じゃないといけないようなので一度マップ型をマーシャルでJSON化(byte)にする方法を試してみました。
[javascript collapse=”false” language=”style=”]
// 一度マップ型をJSON型に変換
tmp, err := json.Marshal(m)
if err != nil {
return err
}
// JSON型を構造体に当て込む
err = json.Unmarshal(tmp, val)
if err != nil {
return err
}
[/javascript]
ここでもう一つ問題”cannot assign to struct field”のエラー文が出てきて、これを調べてみると
「マップ構造は要素の追加によりアドレス空間を再構築しているので、値が変更されるとアドレスも変わる」ようなので、
[javascript collapse=”false” language=”style=”]
err = json.Unmarshal(tmp, val)
// ↓ こっちが正しい
err = json.Unmarshal(tmp, &val)
[/javascript]
構造体のポインタを持たせることで、ここのエラーも回避できました。
この変換時の処理なのですが、どうやらHTMLのname属性と連携しているらしく、構造体に付けれるタグでnameを指定してあげることで指定した構造体へ代入できました。
今回、GO言語について書いてみました。
型変換、実際にアンマーシャルの仕組みをしっかりできていなかった、自分の知識不足が原因でしたので
今回こういった形でそういった問題を解決していく為に調べ、学習できたことは自分にとっても成長できたと思います。
他にも、嵌まった事例もあるので機会がありましたらまた記事にできたらと思います。