dsj60862 2017-01-11 10:59
浏览 15
已采纳

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

I'm looking for some solution to know whats the struct type of the hash. It is possible to do that without try an error method (casting to a specific type and see the cast is successfully)?

Please check the code:

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"
    }
}
  • 写回答

1条回答 默认 最新

  • duanhun3273 2017-01-11 11:09
    关注

    Since the encoding/binary package does not write out type information, it is not possible to tell what type was written / serialized.

    And you're in a worse position that you might originally think: even trying to decode into a value of different type might succeed without errors, so there isn't even a reliable way to tell the type.

    For example if you serialize a value of this type:

    type T struct {
        A int64
        B float64
    }
    

    You can read it into a value of this type:

    type T2 struct {
        B float64
        A int64
    }
    

    It will give no errors because the size of both structs is the same, but obviously you will get different numbers in the fields.

    You are in a little better position if you use encoding/gob, as the gob package does transmit type information, and encoding a value of type T and then decoding it into a value of type T2 would work: order of fields does not matter, and extra or missing fields also do not cause trouble.

    See this example:

    // 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)
    

    Output (try it on the 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}
    

    If you want to be able to detect the type before reading it, you have to take care of it yourself: you have to transmit type information (e.g. name of the type). Or even better, use a serialization method that already does this, for example Google's protocol buffers, and here is the Go implementation for it: github.com/golang/protobuf.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c