在 Go 中检查字节顺序的更好方法

Cub*_*Mew 8 endianness go

我正在编写一个小程序来使用 Go 检查字节序:

var i int = 0x0100
ptr := unsafe.Pointer(&i)
if 0x01 == *(*byte)(ptr) {
    fmt.Println("Big Endian")
} else if 0x00 == *(*byte)(ptr) {
    fmt.Println("Little Endian")
} else {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

import "unsafe"打包转换*int*byte. 但正如https://golang.org/pkg/unsafe/ 中提到的:

包 unsafe 包含绕过 Go 程序类型安全的操作。

导入不安全的包可能是不可移植的,不受 Go 1 兼容性指南的保护。

有没有更好的方法来确定字节序,还是我必须使用不安全的包?

nmu*_*thy 9

尽管仍然依赖于该unsafe包,但 Google 的 TensorFlow API for Go 有一个很好的解决方案(请参阅tensor.go)来测试机器的字节序:

var nativeEndian binary.ByteOrder

func init() {
    buf := [2]byte{}
    *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xABCD)

    switch buf {
    case [2]byte{0xCD, 0xAB}:
        nativeEndian = binary.LittleEndian
    case [2]byte{0xAB, 0xCD}:
        nativeEndian = binary.BigEndian
    default:
        panic("Could not determine native endianness.")
    }
}
Run Code Online (Sandbox Code Playgroud)


Edd*_* R. 5

你想要做的是特定于架构的,据我所知,Go 并没有做很多事情来帮助你确定主机的字节顺序。您使用不安全指针的解决方案可能是您能做的最好的解决方案。

如果您知道要使用的字节顺序并相应地进行编码/解码,则可以使用该encoding/binary包:https : //godoc.org/encoding/binary#ByteOrder

如果你真的需要依赖主机字节顺序,你可能会在设计反模式上大吃一惊,如果可能,你应该尽量避免:https : //commandcenter.blogspot.com/2012/04/byte-order-谬误.html

这里还有一个关于这个话题的关于 golang-nuts 的热烈讨论,辩论双方都表达了意见:https ://groups.google.com/forum/#!topic/golang-nuts/3GEzwKfRRQw

该电子邮件线程有 Russ Cox 的建议,即使用构建约束静态定义所需的字节顺序(或主机字节顺序):

几个月来,我们的代码已经:

var hbo = binary.LittleEndian // hack - 我们想要主机字节顺序!

所以我们可以使用 encoding.Binary 来读取东西。

把它放在一个名为 byteorder_amd64.go 的文件中,它就不再是一个黑客了。它不需要在标准库中。

希望有帮助...