Arrays Golang,将嵌入式结构转换为数组
有没有办法将结构转换为Golang中的值数组 例如,如果我有这种结构(不仅仅是这个): 情况是,我通常使用以下格式将JSON发送到浏览器:Arrays Golang,将嵌入式结构转换为数组,arrays,json,struct,go,Arrays,Json,Struct,Go,有没有办法将结构转换为Golang中的值数组 例如,如果我有这种结构(不仅仅是这个): 情况是,我通常使用以下格式将JSON发送到浏览器: var iota = -1 var data = { NAME: ++iota, ID: ++iota, CREATED_AT: ++iota, UPDATED_AT: ++iota, DELETED_AT: ++iota, // and so on rows: [['kiz',1,'2014-01-01','2014-01-01','2014-01
var iota = -1
var data = {
NAME: ++iota, ID: ++iota, CREATED_AT: ++iota, UPDATED_AT: ++iota, DELETED_AT: ++iota, // and so on
rows: [['kiz',1,'2014-01-01','2014-01-01','2014-01-01'],
['yui',2,'2014-01-01','2014-01-01','2014-01-01'],
['ham',3,'2014-01-01','2014-01-01','2014-01-01'] // and so on
]
};
而不是:
var data = {
rows: [{NAME:'kiz',ID:1,CreatedAt:'2014-01-01',UpdatedAt:'2014-01-01',DeletedAt:'2014-01-01'},
{NAME:'yui',ID:2,CreatedAt:'2014-01-01',UpdatedAt:'2014-01-01',DeletedAt:'2014-01-01'},
{NAME:'ham',ID:3,CreatedAt:'2014-01-01',UpdatedAt:'2014-01-01',DeletedAt:'2014-01-01'} // and so on
]
}
以下是我尝试过的:
import (
"github.com/kr/pretty"
//"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"reflect"
"runtime"
"strings"
"time"
)
// copy the model from above
func Explain(variable interface{}) {
_, file, line, _ := runtime.Caller(1)
//res, _ := json.MarshalIndent(variable, " ", " ")
res := pretty.Formatter(variable)
fmt.Printf("%s:%d: %# v\n", file[len(FILE_PATH):], line, res)
//spew.Dump(variable)
}
func s2a(i interface{}) []interface{} { // taken from https://gist.github.com/tonyhb/5819315
iVal := reflect.ValueOf(i).Elem()
//typ := iVal.Type()
values := make([]interface{}, 0, iVal.NumField())
for i := 0; i < iVal.NumField(); i++ {
f := iVal.Field(i)
//tag := typ.Field(i).Tag.Get("tagname")
//fmt.Println(tag)
// name := typ.Field(i).Name
v := f.Interface()
switch v.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, string, []byte, time.Time:
// do nothing
// case struct{}: // how to catch any embeeded struct?
case Model: // Model (or any embedded/nameless struct) should also converted to array
//arr := s2a() // invalid type assertion: f.(Model) (non-interface type reflect.Value on left)
//arr := s2a(f.Addr().(&Model)) // invalid type assertion: f.Addr().(&Model) (non-interface type reflect.Value on left)
// umm.. how to convert f back to Model?
//for _, e := range arr {
values = append(values, e)
//}
default: // struct? but also interface and map T_T
//v = s2a(&v)
}
values = append(values, v)
}
return values
}
func main() {
//sess, err := mgo.Dial("127.0.0.1")
//Check(err, "unable to connect")
//db := sess.DB("test")
//coll := db.C("coll1")
user := User{}
user.Id = bson.NewObjectId()
user.Name = "kis"
//changeInfo, err := coll.UpsertId(user.Id, user)
//Check(err, "failed to insert")
//Explain(changeInfo)
//Explain(s2a(changeInfo))
user.Name = "test"
Explain(user)
Explain(s2a(&user))
//err = coll.FindId(user.Id).One(&user)
//Check(err, "failed to fetch")
//Explain(user)
//Explain(s2a(&user))
user.CreatedAt = time.Now()
//err = coll.UpdateId(user.Id, user)
//Check(err, "failed to update")
Explain(changeInfo)
Explain(s2a(&user))
user.CreatedAt = user.DeletedAt
//err = coll.FindId(user.Id).One(&user)
//Check(err, "failed to fetch")
Explain(user)
Explain(s2a(&user))
}
导入(
“github.com/kr/pretty”
//“gopkg.in/mgo.v2”
“gopkg.in/mgo.v2/bson”
“反映”
“运行时”
“字符串”
“时间”
)
//从上面复制模型
func Explain(变量接口{}){
_,文件,行,\:=runtime.Caller(1)
//res,:=json.marshallindent(变量“,”)
res:=pretty.Formatter(变量)
fmt.Printf(“%s:%d:%#v\n”,文件[len(文件路径):],行,res)
//排放量转储(变量)
}
func s2a(i接口{})[]接口{}{//取自https://gist.github.com/tonyhb/5819315
iVal:=reflect.ValueOf(i).Elem()
//类型:=iVal.Type()
值:=make([]接口{},0,iVal.NumField())
对于i:=0;i
是否有简单/快速的方法将结构转换为数组(如果其中嵌入了结构,也转换为数组)?为什么不使用reflect.Kind()?这是操场:使用这个包
这里有一些适用于一条记录(任何结构类型),您可以对其进行重构以适用于一段记录
编辑:(复制粘贴以便测量)
主程序包
输入“fmt”
导入“字符串”
导入“反映”
X型结构{
Y字串
Z int
}
func main(){
数据:=X{“yval”,3}
预期结果:=`{“Y”:0,“Z”:1,“行”:[[“yval”,3]]}`
fmt.Println(转换(数据))
fmt.Println(预期结果)
}
func convert(数据接口{})字符串{
v:=反射值(数据)
n:=v.NumField()
st:=反射.TypeOf(数据)
标题:=make([]字符串,n)
对于i:=0;i
如果您愿意为数组表示形式中的字段指定固定顺序,可以通过实现自定义其表示形式来实现。例如:
func (u User) MarshalJSON() ([]byte, error) {
a := []interface{}{
u.Name,
u.Id,
...,
}
return json.Marshal(a)
}
现在,当封送这种类型的变量时,它们将表示为数组。如果还想执行相反的操作(将数组解组到此结构中),还需要实现。这可以以类似的方式完成,使用
json.Unmarshal
解码成[]接口{}
切片,然后取出值。确保UnmarshalJSON
声明为接受指针接收器,否则代码将无法工作(最终将更新结构的副本,而不是结构本身)。我一直认为数组只能包含相同类型的元素,而结构的成员可以是不同类型的。是的,这就是我使用[]接口{}
package main
import "fmt"
import "strings"
import "reflect"
type X struct {
Y string
Z int
}
func main() {
data := X{"yval",3}
expectedResult := `{"Y": 0, "Z": 1, "rows": [["yval", 3]]}`
fmt.Println(convert(data))
fmt.Println(expectedResult)
}
func convert(data interface{}) string {
v := reflect.ValueOf(data)
n := v.NumField()
st := reflect.TypeOf(data)
headers := make([]string, n)
for i := 0; i < n; i++ {
headers[i] = fmt.Sprintf(`"%s": %d`, st.Field(i).Name, i)
}
rowContents := make([]string, n)
for i := 0; i < n; i++ {
x := v.Field(i)
s := fmt.Sprintf("%v", x.Interface())
if x.Type().String() == "string" {
s = `"` + s + `"`
}
rowContents[i] = s
}
return "{" + strings.Join(headers, ", ") + `, "rows": [[` + strings.Join(rowContents, ", ") + "]]}"
}
func (u User) MarshalJSON() ([]byte, error) {
a := []interface{}{
u.Name,
u.Id,
...,
}
return json.Marshal(a)
}