我们如何知道字节数组上有什么样的结构

dferreira:

我正在寻找一些解决方案,以了解哈希的结构类型是什么。是否可以这样做而无需尝试错误方法(广播到特定类型并查看转换是否成功)?

请检查代码:

import (
    "bytes"
    "encoding/binary"
    "fmt"
    "reflect"
)

type T struct {
    A int64
    B float64
}

type D struct {
    A int64
    B float64
    C string
}


func main() {
    // Create a struct and write it.
    t := T{A: 0xEEFFEEFF, B: 3.14}
    buf := &bytes.Buffer{}
    err := binary.Write(buf, binary.BigEndian, t)
    if err != nil {
        panic(err)
    }
    fmt.Println(buf.Bytes())

    out := getType(buf)
    fmt.Println(out)
}

func getType(v interface{})(r string){
    fmt.Println(reflect.TypeOf(v))
    switch t := v.(type) {
        case T:
            return "Is type T"
        case D:
            return "Is type D"
        default:
            _ = t
            return "unknown"
    }
}
icza:

由于encoding/binary程序包不会写出类型信息,因此无法确定是写/序列化了哪种类型。

而且,您可能会遇到一个本来可能会认为更糟糕的情况:即使尝试将其解码为其他类型的值也可能会成功而不会出现错误,因此,甚至没有可靠的方式来区分类型。

例如,如果您序列化此类型的值:

type T struct {
    A int64
    B float64
}

您可以将其读取为以下类型的值:

type T2 struct {
    B float64
    A int64
}

由于两个结构的大小相同,因此不会出现任何错误,但是很明显,您在字段中将获得不同的数字。

如果使用encoding/gob,则位置会更好一些,因为gob程序包确实会传输类型信息,T然后对类型值进行编码,然后将其解码为类型值T2将起作用:字段的顺序无关紧要,多余或缺失的字段也可以不要造成麻烦。

请参阅以下示例:

// Create a struct and write it.
t := T{A: 0xEEFFEEFF, B: 3.14}
fmt.Println("Encoding:", t)
buf := &bytes.Buffer{}
fmt.Println(binary.Write(buf, binary.BigEndian, t))
fmt.Println(buf.Bytes())

fmt.Println(gob.NewEncoder(buf).Encode(t))

t2 := T2{}
fmt.Println(binary.Read(buf, binary.BigEndian, &t2))
fmt.Println(t2)

t2 = T2{}
fmt.Println(gob.NewDecoder(buf).Decode(&t2))
fmt.Println(t2)

输出(在Go Playground上尝试):

Encoding: {4009750271 3.14}
<nil>
[0 0 0 0 238 255 238 255 64 9 30 184 81 235 133 31]
<nil>
<nil>
{1.9810798573e-314 4614253070214989087}
<nil>
{3.14 4009750271}

如果您希望能够在阅读之前检测出类型,则必须自己进行处理:您必须传输类型信息(例如,类型名称)。甚至更好的是,使用已经执行此操作的序列化方法,例如Google的协议缓冲区,这是Go的Go实现:github.com/golang/protobuf

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章