簡體   English   中英

在go中創建異構json數組

[英]Create heterogeneous json array in go

假設我在go中有這樣的結構:

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}]

您可以在結構中添加一個marshal方法來處理邏輯。 有些東西

func (m Message) MarshalJSON() ([]byte, error) {
    data := make([]interface{}, 0)
    data = append(data, m.Args)
    data = append(data, m.Kwargs)
    return json.Marshal(data)
}

在游樂場試試吧

您在輸出中想要的是一個JSON數組, Kwargs包含message結構值的ArgsKwargs字段,因此您可以通過封送以下切片值來獲得所需的內容:

[]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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM