繁体   English   中英

接口转换:接口{}是float64而不是[]接口{} 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 {}是float64,不是[] interface {} [已恢复] panic:接口转换:interface {}是float64,不是[] interface {}

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

我指的是这个问题的答案https://stackoverflow.com/questions/29348262/decoding-pubnub-messages-with-golang-json请指向正确的方向...?

当输入的数据转换成[]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}

根据您粘贴的恐慌消息,似乎出现以下错误:

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)

暂无
暂无

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

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