binary.Write 没有默认字节序,必须显式传入 binary.BigEndian 或 binary.LittleEndian;常见错误是漏传导致小端写入,对接大端系统时解析失败。

binary.Write 默认用大端还是小端?
默认用小端(binary.LittleEndian),不是大端。如果你直接传 binary.Write 一个整数,又没指定编码器,它不会自动按网络字节序(大端)写——这点很多人在序列化协议头或对接 C/Java 系统时踩坑。
关键在于:binary.Write 第三个参数是 binary.ByteOrder 类型,必须显式传入 binary.BigEndian 或 binary.LittleEndian,不能省略。
-
binary.Write本身不带“默认字节序”逻辑,它只是把传入的ByteOrder实例用于底层Write操作 - 常见误用:只传
w io.Writer和v interface{},漏掉binary.BigEndian,结果写出来是小端,对方解析失败 - 支持的类型有限:仅原生整数类型(
int8/uint16/int32等)、float32/float64、数组和结构体(字段需导出且可序列化)
怎么用 binary.Write 写大端整数?
必须显式传入 binary.BigEndian 作为第三个参数。注意:不是设置全局行为,每次调用都得带。
err := binary.Write(w, binary.BigEndian, uint16(0x1234)) // 写入 2 字节:0x12 0x34
如果写结构体,字段顺序即内存布局顺序,binary.Write 会逐字段用你传的 ByteOrder 编码:
立即学习“go语言免费学习笔记(深入)”;
type Header struct {
Magic uint32
Len uint16
}
err := binary.Write(w, binary.BigEndian, Header{Magic: 0x464F4F54, Len: 1024})
- 结构体字段必须导出(首字母大写),否则
binary.Write会报binary.Write: invalid type - 结构体里不能有 slice、map、func、channel 等不可序列化类型
- 字段之间无 padding,和 C 的 packed struct 行为一致;如果有对齐需求,得自己填充字段
为什么 binary.Write 写 float32/float64 要小心?
binary.Write 对浮点数使用 IEEE 754 编码,但字节序只影响整数字节排列,不影响 float 内部位模式的解释顺序——也就是说,binary.BigEndian 写 float32,结果和 math.Float32bits + binary.BigEndian.PutUint32 一样,是标准网络序表示。
- 只要双方都用 IEEE 754,且字节序一致,float 就能互通
- 但某些嵌入式设备或旧系统可能用非标准浮点格式,这时
binary.Write不适用,得手动拆解math.Float32bits后再写 - 不要试图用
binary.Write写complex64或complex128—— 它们不被支持,会 panic
替代方案:什么时候不该用 binary.Write?
当你要写变长数据、需要跳过字段、或目标格式要求特定 padding/校验时,binary.Write 就太死板了。它是一次性扁平写入,没法中途 seek 或 patch。
- 写 protocol buffer、JSON、MessagePack 等格式,直接用对应库,别硬套
binary.Write - 要写带长度前缀的字符串:先写 len(用
binary.BigEndian.PutUint16),再写 []byte,而不是塞进结构体让binary.Write处理 - 性能敏感场景:
binary.Write有反射开销,对高频小数据,用binary.BigEndian.PutUint32直接操作[]byte更快
大端写入的核心就一条:每次调用 binary.Write 都得带上 binary.BigEndian,少一次就会错。没人帮你记着这个。


















