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

I am wanting to build a JSON equivalent of the PurchaseOrder struct below:

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"`
}

In order to do so, I did the following:

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)

The error that I get is:

invalid operation: po["TradeItems"]["sku1"] (type interface {} does not support indexing).

After looking around a bit, I added the following lines to the code and it worked.

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

I don't quite understand what this line means

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

Can someone please explain?

I know the type of po["TradeItems"]. Please explain in-depth. Why should I assert?

You do, but the compiler doesn't. Your po has type map[string]interface{}. So po["TradeItems"] in po["TradeItems"]["sku1"] returns an object of type interface{}, which you can't do anything useful with (not without reflection or type-assertions).

Hence the need to hint the compiler with that type assertion.

I am wanting to build a JSON equivalent of the PurchaseOrder struct below:

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

The easiest way is:

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

Forget about your po := make(map[string]interface{}) and manual manipulation of the map.

If you need to control the JSON keys in your PurchaseOrder object, add the appropriate json tags, as you did for the PRTradeItem definition.