在golang中将interface{}转换为[]byte

37

我试图反序列化一个接口类型的数据。因此,我需要将接口类型转换为[]byte并传递给反序列化函数。

  1. err := json.Unmarshal([]byte(kpi), &a) =>失败
  2. 尝试使用以下方法将接口类型转换为[]byte
    kpidata, res := kpi.([]byte) =>失败,kpidatanil

那么有没有办法可以进行转换呢?

示例:https://play.golang.org/p/5pqQ0DQ94Dp


3
这是一个Go语言的代码示例,它定义了一个名为Person的结构体类型,该类型包含了两个字段:NameAge。在main函数中,创建了一个新的Person实例并将其打印到控制台。 - matthias krull
3
[]byte(fmt.Sprint(data) // 这里的data是interface{}类型。 - Eric
2个回答

25
在你的示例代码中,data 应该是JSON编码的(简单来说就是字符串),因此你使用 Unmarshal 的方式是错误的。
// Unmarshal parses the JSON-encoded data and stores the result
// in the value pointed to by v. If v is nil or not a pointer,
// Unmarshal returns an InvalidUnmarshalError.
func Unmarshal(data []byte, v interface{}) error

Go Playground上试一试,以及this: []string{"art", "football"}

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    // ********************* Marshal *********************
    u := map[string]interface{}{}
    u["name"] = "kish"
    u["age"] = 28
    u["work"] = "engine"
    //u["hobbies"] = []string{"art", "football"}
    u["hobbies"] = "art"

    b, err := json.Marshal(u)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(b))

    // ********************* Unmarshal *********************
    var a interface{}
    err = json.Unmarshal(b, &a)
    if err != nil {
        fmt.Println("error:", err)
    }
    fmt.Println(a)
}

输出:

{"age":28,"hobbies":"art","name":"kish","work":"engine"}
map[name:kish work:engine age:28 hobbies:art]

您想要进行反序列化,因此请尝试这个简单的工作示例([]byte(kpi.(string))):

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var kpi interface{} = st
    var a []Animal
    err := json.Unmarshal([]byte(kpi.(string)), &a)
    if err != nil {
        fmt.Println("error:", err)
    }
    fmt.Println(a)
}

type Animal struct {
    Name  string
    Order string
}

var st = `[
    {"Name": "Platypus", "Order": "Monotremata"},
    {"Name": "Quoll",    "Order": "Dasyuromorphia"}
]`

输出:

[{Platypus Monotremata} {Quoll Dasyuromorphia}]

使用([]byte(*kpi.(*string)))的工作示例:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var kpi interface{} = &st
    var a []Animal
    err := json.Unmarshal([]byte(*kpi.(*string)), &a)
    if err != nil {
        fmt.Println("error:", err)
    }
    fmt.Println(a)
}

type Animal struct {
    Name  string
    Order string
}

var st = `[
    {"Name": "Platypus", "Order": "Monotremata"},
    {"Name": "Quoll",    "Order": "Dasyuromorphia"}
]`

Marshal

(Note: Marshal is a name or username, which cannot be translated without context.)
package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    u := map[string]interface{}{}
    u["1"] = "one"
    b, err := json.Marshal(u)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(b))
}

输出:

{"1":"one"}

我希望这能有所帮助。

太过复杂了。Matthias Krull 在上面已经解决了它。 - Kugel
1
@kish,你是否有map[string]interface {}类型的数据需要进行编组(Marshal)?请注意:反编组(Unmarshal)需要将string[]byte作为输入,而不是map[string]interface {}。因此,为了更好地帮助您,请提供最少量的The Go Playground示例代码。 - wasmup
请查看新编辑:https://play.golang.org/p/j-cjmoFpden。希望对您有所帮助。 - wasmup
1
data 应该是 JSON 编码的(简单来说就是 **字符串**),所以你使用 Unmarshal 的方式是错误的。 - wasmup
1
你说的“如何防止地图?”是什么意思?它会造成什么问题?你应该详细说明一下。我认为这是一个新的问题,所以请创建一个最小完整可验证示例,并清楚地提出问题,这样有人就可以帮助了。 - wasmup
显示剩余3条评论

10

基于Kugel提供的示例的工作示例:

package main

import (
    "fmt"
)

func passInterface(v interface{}) {
    b, ok := v.(*[]byte)
    fmt.Println(ok)
    fmt.Println(b)
}

func main() {
    passInterface(&[]byte{0x00, 0x01, 0x02})
}

播放

如果您不传递引用,它基本上会起到同样的作用:

播放


  1. 我们遇到了编译错误, 代码:passInterface(&kpi) err := json.Unmarshal(kpi, &a) 你的函数
  2. 错误: 无法将 kpi (类型 interface {}) 用作 json.Unmarshal 的参数中的 []byte 类型: 需要类型断言
- kish
3
没有实际的代码,调试问题就相当困难。即使是精简版的 Go Playground 代码也可以。 - matthias krull
我不确定你想做什么。如果你已经有了一个地图,似乎你要解除某些成员:像这样 或者 像这样,或者你不需要解除任何东西,只需要正确的类型断言,以防{}interface的值已经是结构化数据。 - matthias krull

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接