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

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

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

Go
慕沐林林 2022-09-05 18:00:00
我从服务器收到一条消息,如[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,但它太长了。我怎样才能轻松做到?
查看完整描述

1 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

如果您知道websocket上使用的编解码器将始终是json,则可以正式定义并为其提供一个函数来为您进行解码。OrderUnmarshalJSON


import "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


查看完整回答
反对 回复 2022-09-05
  • 1 回答
  • 0 关注
  • 86 浏览
慕课专栏
更多

添加回答

举报

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