golang:json.Unmarshal()返回“无效的内存地址或无指针取消引用”

时间:2015-01-18 16:36:29

标签: json go websocket

我从websocket收到一条json消息,收到json字符串确定。然后我调用json.Unmarshal获得运行时恐慌。我查看了其他示例,但这似乎是另一回事。这是代码:

func translateMessages(s socket) {
    message := make([]byte,4096)
    for {
        fmt.Printf("Waiting for a message ... \n")
        if n, err := s.Read(message); err == nil {
            command := map[string]interface{}{}
            fmt.Printf("Received message: %v (%d Bytes)\n", string(message[:n]), n)
            err := json.Unmarshal(message[:n],&command)
            fmt.Printf("Received command: %v (Error: %s)\n", command, err.Error())
        }
    }
}

这是输出:

Waiting for a message ... 
Received message: {"gruss":"Hello World!"} (24 Bytes)
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x401938]

goroutine 25 [running]:
runtime.panic(0x6f4860, 0x8ec333)

任何暗示可能是什么?

1 个答案:

答案 0 :(得分:1)

如果解码JSON没有错误,此行将会出现混乱:

fmt.Printf("Received command: %v (Error: %s)\n", command, err.Error())

如果err == nil,那么err.Error()会出现nil指针偏差。将行更改为:

fmt.Printf("Received command: %v (Error: %v)\n", command, err)

如果您正在读取套接字,则无法保证s.Read()将读取完整的JSON值。编写此函数的更好方法是:

func translateMessages(s socket) {
  d := json.NewDecoder(s)
  for {
      fmt.Printf("Waiting for a message ... \n")
      var command map[string]interface{}
      err := d.Decode(&command)
      fmt.Printf("Received command: %v (Error: %v)\n", command, err)
      if err != nil {
        return
      }
  }
}

如果您正在使用websockets,那么您应该使用gorilla / webscoket包和ReadJSON来解码JSON值。