接口转换:interface {} 是 float64 而不是 []interface {} PubNub
interface conversion: interface {} is float64 not []interface {} PubNub
我正在尝试获取在订阅端作为 PubNub 消息传递的 JSON 值。代码是
package main
import (
"encoding/json"
"flag"
"fmt"
"github.com/pubnub/go/messaging"
)
type DeployMessages struct {
Server string
Repo string
}
type PNMessage struct {
Messages []DeployMessages
Id string
Channel string
}
func main() {
publishKey := flag.String("pub", "demo", "publish key")
subscribeKey := flag.String("sub", "demo", "subscribe key")
channels := flag.String("channels", "channel1, channel2", "channels to subscribe to")
pubnub := messaging.NewPubnub(*publishKey, *subscribeKey, "", "", false, "", nil)
successChannel := make(chan []byte)
errorChannel := make(chan []byte)
go pubnub.Subscribe(*channels, "", successChannel, false, errorChannel)
subscribeHandler(successChannel, errorChannel, "Subscribe")
}
func (pnm *PNMessage) UnmarshalJSON(bs []byte) error {
var arr []interface{}
err := json.Unmarshal(bs, &arr)
if err != nil {
return err
}
messages := arr[0].([]interface{})
pnm.Messages = make([]DeployMessages, len(messages))
for i, m := range messages {
pnm.Messages[i].Server = m.(map[string]interface{})["server"].(string)
pnm.Messages[i].Repo = m.(map[string]interface{})["repo"].(string)
}
pnm.Id = arr[1].(string)
pnm.Channel = arr[2].(string)
return nil
}
func subscribeHandler(successChannel, errorChannel chan []byte, action string) {
for {
select {
case response, ok := <-successChannel:
if !ok {
break
}
if string(response) != "[]" {
message := PNMessage{}
err := json.Unmarshal([]byte(response), &message)
if err != nil {
break
}
fmt.Println(fmt.Sprintf("%s Response: %s ", action, response))
fmt.Println("")
}
case failure, ok := <-errorChannel:
if !ok {
break
}
if string(failure) != "[]" {
if true {
fmt.Printf("%s Error Response: %s ", action, failure)
fmt.Println("")
}
}
case <-messaging.SubscribeTimeout():
fmt.Printf("Subscirbe request timeout")
}
}
}
消息的格式是这样的
[[{"Repo":"images","Server":"production"}], "149514560987662985",
"channel1"]
这会引发以下恐慌
panic: interface conversion: interface {} is float64, not []interface
{} [recovered]
panic: interface conversion: interface {} is float64, not []interface {}
goroutine 1 [running]:
encoding/json.(*decodeState).unmarshal.func1(0xc042065c20)
C:/Go/src/encoding/json/decode.go:170 +0xf1 panic(0x6548e0, 0xc042009440)
C:/Go/src/runtime/panic.go:489 +0x2dd main.(*PNMessage).UnmarshalJSON(0xc0420093c0, 0xc042009300, 0x3d,
0x40, 0x0, 0xb35198)
C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:43
+0x499 encoding/json.(*decodeState).array(0xc04205b320, 0x64e6a0, 0xc0420093c0, 0x16)
C:/Go/src/encoding/json/decode.go:489 +0xbe4 encoding/json.(*decodeState).value(0xc04205b320, 0x64e6a0,
0xc0420093c0, 0x16)
C:/Go/src/encoding/json/decode.go:399 +0x28e encoding/json.(*decodeState).unmarshal(0xc04205b320, 0x64e6a0,
0xc0420093c0, 0x0, 0x0)
C:/Go/src/encoding/json/decode.go:184 +0x221 encoding/json.Unmarshal(0xc042009300, 0x3d, 0x40, 0x64e6a0,
0xc0420093c0, 0xc042065c98, 0x5f82de)
C:/Go/src/encoding/json/decode.go:104 +0x14f main.subscribeHandler(0xc042030c00, 0xc042030c60, 0x69c4a4, 0x9)
C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:64
+0x222 main.main()
C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:34
+0x27e
我参考了这个问题的答案
请给我指明正确的方向...?
根据您粘贴的紧急消息,错误似乎发生在:
C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:43
这似乎对应于这一行:
messages := arr[0].([]interface{})
您似乎期望数组的那个位置包含另一个数组,但显然您在那里得到了一个 float64,因此出现错误:
interface conversion: interface {} is float64, not []interface {}
你可以添加一些调试来打印出你在 arr
中得到的内容,这样你就可以通过在第 43 行之前添加相应的断言类型:
fmt.Printf("arr: %#v\n", arr)
将传入数据转换为 []interface{}
时,要获得原始数据类型需要很长的 旅程 。这是工作代码:
package main
import (
"encoding/json"
"fmt"
)
type DeployMessage struct {
Server string
Repo string
}
type PNMessage struct {
Messages []DeployMessage
Id string
Channel string
}
// testing to marshal this json
func main() {
// imagine if we have receive our data here.
data := []byte(`[[{"Repo":"images","Server":"production"}], "149514560987662985", "channel1"]`)
var getData []interface{}
err := json.Unmarshal(data, &getData)
if err != nil {
panic(err)
}
fmt.Printf("result getData = %+v\n", getData[0])
getData2 := getData[0].([]interface{})
fmt.Printf("result getData = %+v\n", getData2[0])
getData3 := getData2[0].(map[string]interface{})
var deployMessages []DeployMessage
deployMessages = append(deployMessages, DeployMessage{Server: getData3["Server"].(string), Repo: getData3["Repo"].(string)})
pNMessage := PNMessage{
Messages: deployMessages,
Id: getData[1].(string),
Channel: getData[2].(string),
}
fmt.Printf("result = %+v\n", pNMessage)
}
上面的代码可以工作,但我不喜欢它。 https://play.golang.org/p/U6slzSgaxu
您可以像这样缩短断言数据的代码:
getData2 := getData[0].([]interface{})[0].(map[string]interface{})
repo := getData2["Repo"].(string) // this will get the value of Repo in string.
最终输出:
result = {Messages:[{Server:production Repo:images}] Id:149514560987662985 Channel:channel1}
我正在尝试获取在订阅端作为 PubNub 消息传递的 JSON 值。代码是
package main
import (
"encoding/json"
"flag"
"fmt"
"github.com/pubnub/go/messaging"
)
type DeployMessages struct {
Server string
Repo string
}
type PNMessage struct {
Messages []DeployMessages
Id string
Channel string
}
func main() {
publishKey := flag.String("pub", "demo", "publish key")
subscribeKey := flag.String("sub", "demo", "subscribe key")
channels := flag.String("channels", "channel1, channel2", "channels to subscribe to")
pubnub := messaging.NewPubnub(*publishKey, *subscribeKey, "", "", false, "", nil)
successChannel := make(chan []byte)
errorChannel := make(chan []byte)
go pubnub.Subscribe(*channels, "", successChannel, false, errorChannel)
subscribeHandler(successChannel, errorChannel, "Subscribe")
}
func (pnm *PNMessage) UnmarshalJSON(bs []byte) error {
var arr []interface{}
err := json.Unmarshal(bs, &arr)
if err != nil {
return err
}
messages := arr[0].([]interface{})
pnm.Messages = make([]DeployMessages, len(messages))
for i, m := range messages {
pnm.Messages[i].Server = m.(map[string]interface{})["server"].(string)
pnm.Messages[i].Repo = m.(map[string]interface{})["repo"].(string)
}
pnm.Id = arr[1].(string)
pnm.Channel = arr[2].(string)
return nil
}
func subscribeHandler(successChannel, errorChannel chan []byte, action string) {
for {
select {
case response, ok := <-successChannel:
if !ok {
break
}
if string(response) != "[]" {
message := PNMessage{}
err := json.Unmarshal([]byte(response), &message)
if err != nil {
break
}
fmt.Println(fmt.Sprintf("%s Response: %s ", action, response))
fmt.Println("")
}
case failure, ok := <-errorChannel:
if !ok {
break
}
if string(failure) != "[]" {
if true {
fmt.Printf("%s Error Response: %s ", action, failure)
fmt.Println("")
}
}
case <-messaging.SubscribeTimeout():
fmt.Printf("Subscirbe request timeout")
}
}
}
消息的格式是这样的
[[{"Repo":"images","Server":"production"}], "149514560987662985", "channel1"]
这会引发以下恐慌
panic: interface conversion: interface {} is float64, not []interface {} [recovered] panic: interface conversion: interface {} is float64, not []interface {}
goroutine 1 [running]: encoding/json.(*decodeState).unmarshal.func1(0xc042065c20) C:/Go/src/encoding/json/decode.go:170 +0xf1 panic(0x6548e0, 0xc042009440) C:/Go/src/runtime/panic.go:489 +0x2dd main.(*PNMessage).UnmarshalJSON(0xc0420093c0, 0xc042009300, 0x3d, 0x40, 0x0, 0xb35198) C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:43 +0x499 encoding/json.(*decodeState).array(0xc04205b320, 0x64e6a0, 0xc0420093c0, 0x16) C:/Go/src/encoding/json/decode.go:489 +0xbe4 encoding/json.(*decodeState).value(0xc04205b320, 0x64e6a0, 0xc0420093c0, 0x16) C:/Go/src/encoding/json/decode.go:399 +0x28e encoding/json.(*decodeState).unmarshal(0xc04205b320, 0x64e6a0, 0xc0420093c0, 0x0, 0x0) C:/Go/src/encoding/json/decode.go:184 +0x221 encoding/json.Unmarshal(0xc042009300, 0x3d, 0x40, 0x64e6a0, 0xc0420093c0, 0xc042065c98, 0x5f82de) C:/Go/src/encoding/json/decode.go:104 +0x14f main.subscribeHandler(0xc042030c00, 0xc042030c60, 0x69c4a4, 0x9) C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:64 +0x222 main.main() C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:34 +0x27e
我参考了这个问题的答案
根据您粘贴的紧急消息,错误似乎发生在:
C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:43
这似乎对应于这一行:
messages := arr[0].([]interface{})
您似乎期望数组的那个位置包含另一个数组,但显然您在那里得到了一个 float64,因此出现错误:
interface conversion: interface {} is float64, not []interface {}
你可以添加一些调试来打印出你在 arr
中得到的内容,这样你就可以通过在第 43 行之前添加相应的断言类型:
fmt.Printf("arr: %#v\n", arr)
将传入数据转换为 []interface{}
时,要获得原始数据类型需要很长的 旅程 。这是工作代码:
package main
import (
"encoding/json"
"fmt"
)
type DeployMessage struct {
Server string
Repo string
}
type PNMessage struct {
Messages []DeployMessage
Id string
Channel string
}
// testing to marshal this json
func main() {
// imagine if we have receive our data here.
data := []byte(`[[{"Repo":"images","Server":"production"}], "149514560987662985", "channel1"]`)
var getData []interface{}
err := json.Unmarshal(data, &getData)
if err != nil {
panic(err)
}
fmt.Printf("result getData = %+v\n", getData[0])
getData2 := getData[0].([]interface{})
fmt.Printf("result getData = %+v\n", getData2[0])
getData3 := getData2[0].(map[string]interface{})
var deployMessages []DeployMessage
deployMessages = append(deployMessages, DeployMessage{Server: getData3["Server"].(string), Repo: getData3["Repo"].(string)})
pNMessage := PNMessage{
Messages: deployMessages,
Id: getData[1].(string),
Channel: getData[2].(string),
}
fmt.Printf("result = %+v\n", pNMessage)
}
上面的代码可以工作,但我不喜欢它。 https://play.golang.org/p/U6slzSgaxu
您可以像这样缩短断言数据的代码:
getData2 := getData[0].([]interface{})[0].(map[string]interface{})
repo := getData2["Repo"].(string) // this will get the value of Repo in string.
最终输出:
result = {Messages:[{Server:production Repo:images}] Id:149514560987662985 Channel:channel1}