将接口引入struct

时间:2018-05-07 17:37:38

标签: go

我对golang有点新意,并尝试处理一些websocket数据。

我以以下形式获取数据:

type Event struct {
    Event string      `json:"event"`
    Data  interface{} `json:"data"`
}

Data字段是我想处理的json对象并进入以下结构:

type OrderBook struct {
    Pair      string          `json:"pair"`
    Timestamp string          `json:"timestamp"`
    Broker    string          `json:"broker"`
    Bids      []OrderBookItem `json:"bids"`
    Asks      []OrderBookItem `json:"asks"`
}

type OrderBookItem struct {
    Price  float64
    Amount float64
}
来自websocket函数的

....
case "data":
    publish(e.Data) <--- this is where the error occurs
....

调用:

func publish(data OrderBookResult) {
    log.Println("Publishing trade data...", data)

    o := &OrderBook{}
    o.Pair = "BTCEUR"
    o.Timestamp = data.Timestamp
    o.Broker = "Bitstamp"
    o.Asks = data.Asks
    o.Bids = data.Bids

}

我得到的websocket函数中的错误如下:

cannot use e.Data (type interface {}) as type OrderBookResult in argument to publish: need type assertion

我怎样才能&#34;演员&#34; websocket结构到新的结构和引用字段中,没有在websocket结构上定义。我有一个node.js背景,但我还没有理解我的目标。

THX

1 个答案:

答案 0 :(得分:0)

正如其他人已经注意到的那样,如果接口包含正确的struct类型,则类型断言将是解决您的即时错误的答案。

但是如果您的界面来自JSON解析,它可能包含map[string]interface{}而不是OrderBookResult。请参阅here了解原因。

要解决这个问题,请阅读有关如何创建自定义JSON编组程序的信息。例如,在this blog.下面,我还提供了一种处理map[string]interface{}以便在发布功能中获取数据的方法。

所以你可以在打电话之前键入断言:

....
case "data":

    // Assert that e.Data is in fact a struct of type OrderBookResult
    if dataAsOrderBookResult, ok := e.Data.(OrderBookResult); ok {
        publish(dataAsOrderBookResult)
    } else {
        // handle error etc
        ...
    }

....

或者更改发布函数的签名并在其中键入断言参数:

func publish(data interface{}) {
    log.Println("Publishing trade data...", data)

    o := &OrderBook{}
    // Type switch
    switch v := data.(type) {
    case OrderBookResult:
        o.Pair = "BTCEUR"
        o.Timestamp = v.Timestamp
        o.Broker = "Bitstamp"
        o.Asks = v.Asks
        o.Bids = v.Bids
    case map[string]interface{}:
        o.Pair = "BTCEUR"
        o.Timestamp = v["Timestamp"].(string)
        o.Broker = "Bitstamp"
        // here again you need to type assert correctly and it may be a map again
        //o.Asks = v["Asks"].(OrderBookItem)
        //o.Bids = v["Bids"].(OrderBookItem)
    default:
        // error handling etc.
        ...
    } 
...    
}