【问题标题】:interface{} to []byte conversion in golanggolang 中的 interface{} 到 [] 字节转换
【发布时间】:2018-08-06 23:27:17
【问题描述】:

我正在尝试解组接口类型的数据。所以我需要将接口类型转换为 []byte 并将其传递给 unmarshall。 我试过了

  1. err := json.Unmarshal([]byte(kpi), &a) => 失败
  2. 我厌倦了通过使用将接口转换为字节 kpidata, res := kpi.([]byte) => 失败,kpidata 为零

那么有什么办法可以转换吗?

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

【问题讨论】:

标签: json go


【解决方案1】:

在您的sample 代码中,data 应该是 JSON 编码(简单来说是 String),因此您以错误的方式使用 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

The Go Playgroundthis: []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]

你想Unmarshal它,所以试试this简单的工作示例([]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}]

工作 example 使用 ([]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:

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 在上面解决了它。
  • 我们得到 panic 错误代码:err := json.Unmarshal([]byte(kpi.(string)), &a) " panic: interface conversion: interface is map[string]interface {},不是字符串“
  • @kish 你有map[string]interface {} 类型并且需要Marshal 吗?注意:Unmarshal 需要 []bytestring 作为输入而不是 map[string]interface {} 。所以为了更好的帮助,请提供最少的The Go Playground 示例代码。
  • data 应该是 JSON 编码(简单来说 String)所以你使用 Unmarshal 的方式是错误的
  • “如何防止地图出现”是什么意思。它会产生什么问题?你应该详细说明。我认为这是新问题,所以create a Minimal, Complete, and Verifiable example 并清楚地提出新问题,以便有人可以提供帮助。
【解决方案2】:

基于 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})
}

Play

如果你不传递引用,它的工作原理基本相同:

Play

【讨论】:

  • 1.我们得到编译错误,代码: passInterface(&kpi) err := json.Unmarshal(kpi, &a) your function 2. error : cannot use kpi (type interface {}) as type []byte in argument to json.Unmarshal:需要类型断言
  • 在没有实际代码的情况下很难调试您的问题,真的。即使是 Go Playground 的精简版也可以。
  • 我不确定您要做什么。如果您已经有地图,您似乎必须解组某些成员:like thislike this,或者您不需要解组任何内容,只需要正确的类型断言,以防{}interface 的值是结构化数据已经。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-17
  • 2014-12-30
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
  • 2019-09-22
  • 2017-01-17
相关资源
最近更新 更多