LoginSignup
0
0

More than 1 year has passed since last update.

GO言語で、確保した配列に、Mapデータからデータ入力する方法

Posted at

前置き

SQLの汎用性があるプログラムを自作中にSQLからデータを読み取る際に、読み取ったデータを配列に変換させる際で汎用性プログラムが作れないか試してみたので、記録する・

説明など

構造体を作ったり操作するためにreflect関数というだいぶ便利なものがあるのでデバッガと組み合わせていろいろと試していた。
ポインタ操作がかなりめんどくさいけど、一つづつ調整していくと出来上がるものができたからだいぶ楽になった。

実装プログラム

main.go
package main

import (
	"fmt"
	"reflect"
)

func mapToStruct(s map[string]interface{}, i interface{}) {

	sv := reflect.ValueOf(i)
	if sv.Type().Kind() != reflect.Pointer {
		fmt.Println(sv.Type().Kind())
		return
	}
	if len(s) == 0 {
		return
	}
	ii := sv.Elem().Interface()
	tStruct := reflect.TypeOf(ii).Elem()
	vStruct := reflect.New(tStruct)
	ckStruct := reflect.TypeOf(vStruct.Elem().Interface())
	for i := 0; i < ckStruct.NumField(); i++ {
		f := ckStruct.Field(i)
		v := vStruct.Elem().FieldByName(f.Name)
		ss := s[f.Name]
		switch f.Type.Kind() {
		case reflect.Int & reflect.TypeOf(ss).Kind():
			v.SetInt(int64(ss.(int)))
		case reflect.String & reflect.TypeOf(ss).Kind():
			v.SetString(ss.(string))
		}
	}
	out := vStruct.Elem()
	v := sv.Elem()
	v.Set(reflect.Append(v, out))

}

type User struct {
	Name string
	Age  int
}

func main() {
	strmap := map[string]interface{}{
		"Name": "bsg",
		"Age":  10,
	}
	strmap2 := map[string]interface{}{
		"Name": "bsg1",
		"Age":  "10",
	}
	str := []User{}
	mapToStruct(strmap, &str)
	mapToStruct(strmap2, &str)
	fmt.Println(str)
}

この関数を実行すると以下の通り帰ってくる

[{bsg 10} {bsg1 0}]

結果的に、名前に対応したmapの型を合わせないと配列に設定して追加しないし特別なエラーが発生ないことも確認できた。

まとめ

reflect関数とinterfaceの型を組み合わせることで、だいぶ汎用性がある配列を作る関数プログラムができた。
これから、SQLの汎用プログラム作成に役に立つだろう

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0