当我的值是结构类型时,如何填充map [string]接口{}?

时间:2019-04-03 09:35:15

标签: go

我想构建与以下PurchaseOrder结构等效的JSON:

type PurchaseOrder struct {
    State      string
    FsmName    string
    Supplier   string
    Receiver   string
    TradeItems map[string]PRTradeItem
}

type PRTradeItem struct {
    Quantity float64 `json:"quantity"`
    Supplier string  `json:"supplier"`
    Receiver string  `json:"receiver"`

    PricePerUnit float64 `json:"pricePerUnit"`
}

为此,我执行了以下操作:

po := make(map[string]interface{})
po["Sender"] = "org2"
po["Receiver"] = "org1"
po["TradeItems"] = make(map[string]PRTradeItem)
po["TradeItems"]["sku1"] = PRTradeItem{Quantity: 100, Supplier: "org2", Receiver: "org1", PricePerUnit: 10.5}
poAsBytes, _ := JSON.Marshal(po)

我得到的错误是:

  

无效操作:po [“ TradeItems”] [“ sku1”](类型接口{}不支持索引)。

四处浏览后,我在代码中添加了以下几行,就可以了。

internalMap, ok := po["TradeItems"].(map[string]PRTradeItem)
if !ok{

    panic("why???")
}
if ok{  
    internalMap["sku1"] = PRTradeItem{Quantity:100,Supplier:"org2", Receiver:"org1", PricePerUnit:10.5}
}

我不太明白这行是什么意思

internalMap, ok := po["TradeItems"].(map[string]PRTradeItem)

有人可以解释吗?

2 个答案:

答案 0 :(得分:6)

  

我想构建与以下PurchaseOrder结构等效的JSON:

type PurchaseOrder struct {
    State      string
    FsmName    string
    Supplier   string
    Receiver   string
    TradeItems map[string]PRTradeItem
}

最简单的方法是:

po := PurchaseOrder{
    State:      "paid",
    Supplier:   "Acme, Inc.",
    TradeItems: map[string]PRTradeItem{
        "sku1": PRTradeItem{Quantity: 100, Supplier: "org2", ... },
    },
}
poAsBytes, err := json.Marshal(po)

忘记您的po := make(map[string]interface{})和地图的手动操作。

如果您需要控制PurchaseOrder对象中的JSON密钥,请像对json定义那样添加适当的PRTradeItem标签。

答案 1 :(得分:3)

  

我知道po["TradeItems"]的类型。请深入解释。我为什么要断言?

可以,但是编译器不可以。您的po的类型为map[string]interface{}。因此,po["TradeItems"]中的po["TradeItems"]["sku1"]返回类型为interface{}的对象,您不能做任何有用的事情(不是没有反射或类型断言)。

因此需要使用该类型断言来提示编译器。