简体   繁体   English

接口转换:接口{}是float64而不是[]接口{} PubNub

[英]interface conversion: interface {} is float64 not []interface {} PubNub

I am trying to get at the JSON values that are passed as a PubNub message on the subscribe end. 我试图获取在订阅端作为PubNub消息传递的JSON值。 the code for this is 该代码是

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

The format of the message is this 消息的格式是这个

[[{"Repo":"images","Server":"production"}], "149514560987662985", "channel1"] [[{“ Repo”:“ images”,“ Server”:“ production”}],“ 149514560987662985”,“ channel1”]

This throws the following panic 这引发了以下恐慌

panic: interface conversion: interface {} is float64, not []interface {} [recovered] panic: interface conversion: interface {} is float64, not []interface {} panic:接口转换:interface {}是float64,不是[] interface {} [已恢复] panic:接口转换:interface {}是float64,不是[] 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 goroutine 1 [运行中]: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编码/json.(*decodeState).array(0xc04205b320,0x64e6a0,0xc0420093c0,0x16)C:/Go/src/encoding/json/decode.go:489 + 0xbe4编码/json.(*decodeState ).value(0xc04205b320,0x64e6a0,0xc0420093c0,0x16)C:/Go/src/encoding/json/decode.go:399 + 0x28e encoding / json。(* decodeState).unmarshal(0xc04205b320,0x64e6a0,0xc0420093c )C:/Go/src/encoding/json/decode.go:184 + 0x221编码/json.Unmarshal(0xc042009300、0x3d、0x40、0x64e6a0、0xc0420093c0、0xc042065c98、0x5f82de)C:/ Go / src / encoding / json / encode.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 /main.go:64 + 0x222 main.main()C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:34 + 0x27e

I was referencing the answer to this question https://stackoverflow.com/questions/29348262/decoding-pubnub-messages-with-golang-json Please point me in the right direction...? 我指的是这个问题的答案https://stackoverflow.com/questions/29348262/decoding-pubnub-messages-with-golang-json请指向正确的方向...?

When converting incoming data to []interface{} , this is going to be long journey to get to the original data type. 当输入的数据转换成[]interface{}这将是长的旅程得到原来的数据类型。 Here is the working code : 这是工作代码:

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)

}

Above code will works but I don't like it. 上面的代码可以用,但是我不喜欢。 https://play.golang.org/p/U6slzSgaxu https://play.golang.org/p/U6slzSgaxu

You can shorten the code the assert your data like this : 您可以像这样缩短声明数据的代码:

getData2 := getData[0].([]interface{})[0].(map[string]interface{})
repo := getData2["Repo"].(string) // this will get the value of Repo in string.

final output : 最终输出:

result  = {Messages:[{Server:production Repo:images}] Id:149514560987662985 Channel:channel1}

According to the panic message you pasted, error seems to be occurring in: 根据您粘贴的恐慌消息,似乎出现以下错误:

C:/Users/olmadmin/Documents/work/Go/src/DeploymentServer/main.go:43

Which seems to correspond to this line: 这似乎对应于这一行:

messages := arr[0].([]interface{})

You seem to be expecting that position to the array to hold another array, but apparently you are getting a float64 there, and thus the error: 您似乎期望该数组的位置可以容纳另一个数组,但是显然您在此处得到一个float64,因此出现错误:

interface conversion: interface {} is float64, not []interface {}

You can add some debugging to print out what you are getting in arr at that point, so that you can then assert the type accordingly by adding this before that line 43: 您可以添加一些调试信息以打印出此时arr ,以便随后可以通过在第43行之前添加以下内容来断言类型:

fmt.Printf("arr: %#v\n", arr)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM