在 Go 中,如何将结构转换为字节数组?

我有一个我定义的 struct 的实例,我想把它转换成一个字节数组。我试过[] byte (my _ struct) ,但是没有用。另外,我被指向 二进制程序包,但是我不确定我应该使用哪个函数,以及我应该如何使用它。如果能给我个例子就太好了。

150200 次浏览

我猜你想要 C 处理这件事的方式。没有什么方法可以做到这一点。您必须为结构定义自己的序列化和反序列化。二进制包将帮助您进行编码 字节数组中可以添加到字节数组中的字段,但是您将负责指定字节数组中保存结构中字段的长度和偏移量。

您的其他选择是使用其中一个编码包: http://golang.org/pkg/encoding/,例如 gob 或 json。

编辑:

因为您希望这样做,以便像您在注释中所说的那样生成散列,所以最容易做的事情是使用 []byte(fmt.Sprintf("%v", struct)),如下所示: http://play.golang.org/p/yY8mSdZ_kf

你有没有考虑过把它连载到 bson? http://labix.org/gobson

您应该使用字节缓冲区代替字符串,其他建议的方法创建一个 SHA1的可变长度,SHA1的标准长度必须是20字节(160位)

package main


import (
"crypto/sha1"
"fmt"
"encoding/binary"
"bytes"
)


type myStruct struct {
ID   string
Data string
}


func main() {
var bin_buf bytes.Buffer
x := myStruct{"1", "Hello"}
binary.Write(&bin_buf, binary.BigEndian, x)
fmt.Printf("% x", sha1.Sum(bin_buf.Bytes()))
}

自己试试: http://play.golang.org/p/8YuM6VIlLV

这是一个非常简单的方法,而且效果很好。

一种可能的解决方案是 "encoding/gob"标准包。Gob 包创建一个编码器/解码器,它可以将任何结构编码成一个字节数组,然后将该数组解码回一个结构。有一个很棒的职位,给你

正如其他人指出的,有必要使用这样的包,因为从本质上讲,结构具有未知的大小,不能转换为字节数组。

我包含了一些代码和 玩吧

package main


import (
"bytes"
"encoding/gob"
"fmt"
"log"
)


type P struct {
X, Y, Z int
Name    string
}


type Q struct {
X, Y *int32
Name string
}


func main() {
// Initialize the encoder and decoder.  Normally enc and dec would be
// bound to network connections and the encoder and decoder would
// run in different processes.
var network bytes.Buffer        // Stand-in for a network connection
enc := gob.NewEncoder(&network) // Will write to network.
dec := gob.NewDecoder(&network) // Will read from network.
// Encode (send) the value.
err := enc.Encode(P{3, 4, 5, "Pythagoras"})
if err != nil {
log.Fatal("encode error:", err)
}


// HERE ARE YOUR BYTES!!!!
fmt.Println(network.Bytes())


// Decode (receive) the value.
var q Q
err = dec.Decode(&q)
if err != nil {
log.Fatal("decode error:", err)
}
fmt.Printf("%q: {%d,%d}\n", q.Name, *q.X, *q.Y)
}

我知道这个帖子很老了,但是没有一个答案被接受,而且有一个非常简单的方法可以做到这一点。

Https://play.golang.org/p/tedsy455ebd

游乐场的重要密码

import (
"bytes"
"fmt"
"encoding/json"
)


type MyStruct struct {
Name string `json:"name"`
}


testStruct := MyStruct{"hello world"}
reqBodyBytes := new(bytes.Buffer)
json.NewEncoder(reqBodyBytes).Encode(testStruct)


reqBodyBytes.Bytes() // this is the []byte

我们来看一下 < a href = “ https://blog.golang.org/go- 切片使用和內部”rel = “ nofollow norefrer”> https://blog.golang.org/go-slices-usage-and-internals 特别是内部切片。这个想法是模仿 slice 的内部结构,并指向 struct 而不是字节序列:

package main


import (
"fmt"
"unsafe"
)


// our structure
type A struct {
Src int32
Dst int32
SrcPort uint16
DstPort uint16
}


// that is how we mimic a slice
type ByteSliceA struct {
Addr *A
Len int
Cap int
}


func main() {
// structure with some data
a := A{0x04030201,0x08070605,0x0A09, 0x0C0B}


// create a slice structure
sb := &ByteSliceA{&a, 12, 12} // struct is 12 bytes long, e.g. unsafe.Sizeof(a) is 12


// take a pointer of our slice mimicking struct and cast *[]byte on it:
var byteSlice []byte = *(*[]byte)(unsafe.Pointer(sb))


fmt.Printf("%v\n", byteSlice)
}

产出:

[1 2 3 4 5 6 7 8 9 10 11 12]

Https://play.golang.org/p/rh_yrscrdv6

package main


import (
"crypto/sha1"
"fmt"
"encoding/binary"
"bytes"
)


type myStruct struct {
ID   [10]byte
Data [10]byte
}


func main() {
var bin_buf bytes.Buffer
x := myStruct{"1", "Hello"}
binary.Write(&bin_buf, binary.BigEndian, x)
fmt.Printf("% x", sha1.Sum(bin_buf.Bytes()))
}

Write 采用一个固定长度的内存分配数据类型的结构。

序列化可能是合适的答案。

但是如果您同意不安全并且实际上需要将 struct 读取为字节,那么依赖字节 数组内存表示可能比依赖字节 切片内部结构要好一些。

type Struct struct {
Src int32
Dst int32
SrcPort uint16
DstPort uint16
}


const sz = int(unsafe.SizeOf(Struct{}))
var asByteSlice []byte = (*(*[sz]byte)(unsafe.Pointer(&struct_value)))[:]

工程和提供读写视图成结构,零拷贝。两个“不安全”应该足够暗示,它可能会严重中断。

只要用 Json Marshall 这是一个非常简单的方法。

newFsConfig := dao.ConfigEntity{EnterpriseId:"testing"}
newFsConfigBytes, _ := json.Marshal(newFsConfig)

Marshall 是将 struct 转换为[] byte 的最佳选项,参见下面的例子:

package main


import (
"encoding/json"
"fmt"
)


type ExampleConvertToByteArray struct {
Name    string
SurName string
}


func main() {


example := ExampleConvertToByteArray{
Name:    "James",
SurName: "Camara",
}
    

var exampleBytes []byte
var err error


exampleBytes, err := json.Marshal(example)
if err != nil {
print(err)
return
}


fmt.Println(string(exampleBytes))
}

去操场-> https://play.golang.org/p/mnB9Cxy-2H3