1 回答

TA貢獻(xiàn)1818條經(jīng)驗 獲得超8個贊
索引 3 處的數(shù)組元素描述了索引 4 處的變體 JSON 的類型。
以下是如何將 JSON 解碼為 Go 值。首先,為 JSON 的每個變體部分聲明 Go 類型:
type PrescenceDiff struct {
Joins map[string]*Presence // declaration of Presence type to be supplied
Leaves map[string]*Presence
}
type Message struct {
Body string
}
聲明一個將類型字符串與 Go 類型相關(guān)聯(lián)的映射:
var messageTypes = map[string]reflect.Type{
"presence_diff": reflect.TypeOf(&PresenceDiff{}),
"message": reflect.TypeOf(&Message{}),
// add more types here as needed
}
將變體部分解碼為原始消息。使用索引 3 處的元素中的名稱來創(chuàng)建適當(dāng) Go 類型的值并解碼為該值:
func decode(data []byte) (interface{}, error) {
var messageType string
var raw json.RawMessage
v := []interface{}{nil, nil, nil, &messageType, &raw}
err := json.Unmarshal(data, &v)
if err != nil {
return nil, err
}
if len(raw) == 0 {
return nil, errors.New("no message")
}
t := messageTypes[messageType]
if t == nil {
return nil, fmt.Errorf("unknown message type: %q", messageType)
}
result := reflect.New(t.Elem()).Interface()
err = json.Unmarshal(raw, result)
return result, err
}
使用類型開關(guān)訪問消息的變體部分:
defer ws.Close()
for {
_, data, err := ws.ReadMessage()
if err != nil {
log.Printf("Read error: %v", err)
break
}
v, err := decode(data)
if err != nil {
log.Printf("Decode error: %v", err)
continue
}
switch v := v.(type) {
case *PresenceDiff:
fmt.Println(v.Joins, v.Leaves)
case *Message:
fmt.Println(v.Body)
default:
fmt.Printf("type %T not handled\n", v)
}
}
- 1 回答
- 0 關(guān)注
- 132 瀏覽
添加回答
舉報