在 Go 中将结构转换为字节切片的紧凑方法是什么?
What's a compact way of casting a struct into a byte slice in Go?
在编写网络代码时,我们经常发现自己从字节切片填充结构以访问对象形式的数据。
让我们采用这个结构
type PACKETHEAD struct {
Type uint16
Size uint16
Hash uint32
}
和一个以某种方式填充了数据的字节片
data := make([]byte, 1024)
我的解决方案是
var pkthead PACKETHEAD
pktsiz := unsafe.Sizeof(pkthead)
pktbuf := bytes.NewReader(buf[:pktsiz])
err = binary.Read(pktbuf, binary.BigEndian, &pkthead)
if err != nil {
// handle it
}
但是
它使用unsafe
每次转换需要大约 7 行代码(如果我们有数百个不同的数据包会怎么样)
不能简单地打包到 Cast(*struct, data)
函数中
无法控制结构填充,如果 go 的编译器决定在网络一端的成员之间添加额外的字节怎么办?
binary.Read 如果我没记错的话执行数据复制(这不一定是骗局)
在 C 中,只需 #pragma pack(1)
在网络两端就一种字节顺序达成一致
最后 PACKETHEAD* pkt = (PACKETHEAD*)dataptr;
我们怎样才能用 Go 实现同样的事情?
祝你有美好的一天,
克里斯
gopack
的无耻插件,我(和其他人)为支持 Go 中的位打包而编写的库。注意:如果这是一个问题,它会在后台使用不安全的操作。
在编写网络代码时,我们经常发现自己从字节切片填充结构以访问对象形式的数据。
让我们采用这个结构
type PACKETHEAD struct {
Type uint16
Size uint16
Hash uint32
}
和一个以某种方式填充了数据的字节片
data := make([]byte, 1024)
我的解决方案是
var pkthead PACKETHEAD
pktsiz := unsafe.Sizeof(pkthead)
pktbuf := bytes.NewReader(buf[:pktsiz])
err = binary.Read(pktbuf, binary.BigEndian, &pkthead)
if err != nil {
// handle it
}
但是
它使用
unsafe
每次转换需要大约 7 行代码(如果我们有数百个不同的数据包会怎么样)
不能简单地打包到
Cast(*struct, data)
函数中无法控制结构填充,如果 go 的编译器决定在网络一端的成员之间添加额外的字节怎么办?
binary.Read 如果我没记错的话执行数据复制(这不一定是骗局)
在 C 中,只需 #pragma pack(1)
在网络两端就一种字节顺序达成一致
最后 PACKETHEAD* pkt = (PACKETHEAD*)dataptr;
我们怎样才能用 Go 实现同样的事情?
祝你有美好的一天, 克里斯
gopack
的无耻插件,我(和其他人)为支持 Go 中的位打包而编写的库。注意:如果这是一个问题,它会在后台使用不安全的操作。