如何使用Go中接口数组中的值初始化结构?

我从服务器收到一条消息,如[0,“on”,[6,1,5,“market”,45.7]],并将其保存到[]interface{}变量。我想用这个数组的值初始化结构。我对Go来说是全新的,并尝试这样做:


import "golang.org/x/net/websocket"

...

var msg []interface{}

// Server send response: `[0,"on",[6,1,5,"market",45.7]]`

if err := websocket.Message.Receive(ws, &msg); err != nil {

    logger.Println(err)

} else {

    type Order struct {

        ID int32,

        GID int32,

        CID int32,

        Type string,

        Amount float64

    }

    

    // here msg is [0,"on",[6,1,5,"market",45.7]]

    

    switch msg[1] {

    case "on":

        if rawOrder, ok := msg[2].([]interface{}); ok {

            order := Order{int32(rawOrder[0]), int32(rawOrder[1]), int32(rawOrder[2]), string(rawOrder[3]), float64(rawOrder[4])}

        }

}

但是我收到一个错误“无法将'interface{}'类型的表达式转换为'int32'”类型,下一步是为每个rawOrder[i]类型使用switch,但它太长了。我怎样才能轻松做到?


慕沐林林
浏览 87回答 1
1回答

RISEBY

如果您知道websocket上使用的编解码器将始终是json,则可以正式定义并为其提供一个函数来为您进行解码。OrderUnmarshalJSONimport "golang.org/x/net/websocket"type Order struct {    ID, GID, CID int32    Type         string    Amount       float64}func (o *Order) UnmarshalJSON(data []byte) error {    var first []json.RawMessage    err := json.Unmarshal(data, &first)    if err != nil {        return fmt.Errorf("invalid order, must be array: %w", err)    }    if len(first) != 3 {        return fmt.Errorf("invalid order, length must be 3, got %d", len(first))    }    var second string    err = json.Unmarshal(first[1], &second)    if err != nil {        return fmt.Errorf("invalid order, second element must be string: %w", err)    }    switch second {    case "on":        var third []json.RawMessage        err = json.Unmarshal(first[2], &third)        if err != nil {            return fmt.Errorf("invalid order, third element must be array: %w", err)        }        if len(third) != 5 {            return fmt.Errorf("invalid order, element 3 length must be 5, got %d", len(third))        }        for i, f := range []interface{}{&o.ID, &o.GID, &o.CID, &o.Type, &o.Amount} {            err = json.Unmarshal(third[i], f)            if err != nil {                return fmt.Errorf("invalid order, wrong type for element 3[%d]: %w", i, err)            }        }        return nil    }    return fmt.Errorf("invalid order, unknown type %q", second)}...var msg *Order// Server send response: `[0,"on",[6,1,5,"market",45.7]]`if err := websocket.JSON.Receive(ws, &msg); err != nil {    logger.Println(err)}// msg is now an &Order{ID:6, GID:1, CID:5, Type:"market", Amount:45.7}}该功能之所以巨大,是因为您的API很糟糕。如果您控制服务器;那么你应该避免在同一数组中使用混合类型,你应该避免对关系数据使用数组。UnmarshalJSON
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go