duanfengdian7014 2017-12-15 13:22
浏览 22
已采纳

戈兰超范围界面{}

I'am trying to develop simple chat application. And User talks coming from webservice like this json. And I unmarshaling this json as map[string]interface{}. My question is I am trying to get all "talk_messages" in for loop. But I can't.

{
"talk_id": 0,
"receiver_id": 1,
"receiver_name":"Jack",
"sender_id": 0,
"talk_messages":[
    {
        "message_id": 0,
        "body": "Helooo",
        "send_date": "12/3/2017 4:57:15 PM",
        "sender_id": 0,
        "talk_id": 0
    },
    {
        "message_id": 1,
        "body": "Helooo",
        "send_date": "12/3/2017 4:58:15 PM",
        "sender_id": 1,
        "talk_id": 0
    },
    {
        "message_id": 2,
        "body": "Whatsapp",
        "send_date": "12/3/2017 4:59:22 PM",
        "sender_id": 0,
        "talk_id": 0
    },
    {
        "message_id": 3,
        "body": "Lorem impus",
        "send_date": "12/3/2017 5:01:15 PM",
        "sender_id": 1,
        "talk_id": 0
    }
]
}

here is my for loop. What is my problem?

var talkData map[string]interface{}

if unMarshalError := json.Unmarshal([]byte(data), &talkData); unMarshalError != nil {
    fmt.Println("Talk initialize error :", unMarshalError)
}

idString := fmt.Sprintf("%v", talkData["talk_id"])
talk.id, _ = strconv.ParseInt(idString, 10, 64)

talk.playerOneId = fmt.Sprintf("%v", talkData["receiver_id"])
talk.playerTwoId = fmt.Sprintf("%v", talkData["sender_id"])
talk.receiverName = fmt.Sprintf("%v", talkData["receiver_name"])

for _, val := range talkData["talk_messages"] {
    fmt.Println(val)
}
fmt.Println(talk.id, talk.playerOneId, talk.playerTwoId)
  • 写回答

1条回答 默认 最新

  • douyueqing1530 2017-12-15 17:23
    关注

    Since you're unmarshaling into a generic value (map[string]interface{}) you'll need to use a type assertion to convert the value referenced by the "talk_messages" key into a slice of generic types ([]interface{}) so they can be iterated using the "range" keyword, e.g.:

    messages := talkData["talk_messages"].([]interface{})
    // assert a slice type --------------^^^^^^^^^^^^^^^^
    
    for i, message := range messages {
        fmt.Printf("OK: message %d => %s
    ", i, message)
    }
    

    Even better, since you know the structure of the data ahead of time, and assuming it is consistent, you could define struct types in which to marshal that data directly and not have to worry about the interface{} type at all:

    type TalkData struct {
      Id           int           `json:"talk_id"`
      ReceiverId   int           `json:"receiver_id"`
      ReceiverName string        `json:"receiver_name"`
      SenderId     int           `json:"sender_id"`
      Messages     []TalkMessage `json:"talk_messages"`
    }
    
    type TalkMessage struct {
      Id       int    `json:"message_id"`
      Body     string `json:"body"`
      SendDate string `json:"send_date"`
      SenderId int    `json:"sender_id"`
      TalkId   int    `json:"talk_id"`
    }
    
    talkData := &TalkData{}
    err := json.Unmarshal([]byte(data), &talkData)
    if err != nil {
      // Handle err...
    }
    
    for i, message := range talkData.Messages {
      // Process message...
    }
    

    Also, as mentioned by commenters, you should handle errors in some way other than simply printing them otherwise the program will do unexpected things.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用