为了账号安全,请及时绑定邮箱和手机立即绑定

在go中创建异构json数组

在go中创建异构json数组

Go
慕工程0101907 2023-05-08 17:52:37
假设我有一个这样的结构:type Message struct {    Args   []interface{}    Kwargs map[string]interface{}}message := Message{                                                                                                                                                                                                []interface{}{1, 2, 3, 4},                                                                                                                                                                                     map[string]interface{}{"a": 2, "b": 3},                                                                                                                                                                    }我应该如何编组消息以获得这样的 JSON?[[1,2,3,4], {"a": 2, "b":3}]
查看完整描述

2 回答

?
慕姐4208626

TA贡献1852条经验 获得超7个赞

您可以向您的结构添加一个编组方法来处理逻辑。在行的东西


func (m Message) MarshalJSON() ([]byte, error) {

    data := make([]interface{}, 0)

    data = append(data, m.Args)

    data = append(data, m.Kwargs)

    return json.Marshal(data)

}


在操场上试试


查看完整回答
反对 回复 2023-05-08
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

您在输出中想要的是一个 JSON 数组,其中包含您的结构值的Args和字段,因此您可以通过编组以下切片值来获得您想要的内容:Kwargsmessage


[]interface{}{message.Args, message.Kwargs}

例如:


message := Message{

    []interface{}{1, 2, 3, 4},

    map[string]interface{}{"a": 2, "b": 3},

}


err := json.NewEncoder(os.Stdout).

    Encode([]interface{}{message.Args, message.Kwargs})


fmt.Println(err)

上面的输出(在Go Playground上试试):


[[1,2,3,4],{"a":2,"b":3}]

<nil>

这适用于这种特定情况。如果你想要一个像数组元素一样编组结构值字段的通用解决方案,你可以创建一个辅助函数,将字段“打包”到一个切片中:


func getFields(i interface{}) (res []interface{}) {

    v := reflect.ValueOf(i)

    if v.Kind() == reflect.Ptr {

        v = v.Elem()

    }

    if v.Kind() != reflect.Struct {

        return nil

    }


    for i := 0; i < v.NumField(); i++ {

        f := v.Field(i)

        if f.CanInterface() {

            res = append(res, f.Interface())

        }

    }

    return res

}

以上getFields()接受结构值和指向结构的指针。使用它的例子:


message := Message{

    []interface{}{1, 2, 3, 4},

    map[string]interface{}{"a": 2, "b": 3},

}


err := json.NewEncoder(os.Stdout).Encode(getFields(message))

fmt.Println(err)


err = json.NewEncoder(os.Stdout).Encode(getFields(&message))

fmt.Println(err)

输出(在Go Playground上尝试):


[[1,2,3,4],{"a":2,"b":3}]

<nil>

[[1,2,3,4],{"a":2,"b":3}]

<nil>


查看完整回答
反对 回复 2023-05-08
  • 2 回答
  • 0 关注
  • 135 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信