Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Golang,将嵌入式结构转换为数组_Arrays_Json_Struct_Go - Fatal编程技术网

Arrays Golang,将嵌入式结构转换为数组

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

有没有办法将结构转换为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-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)
}