文章
Go语言中的binary.LittleEndian的用法
在 Go 语言中,binary.LittleEndian.PutUint16(node[0:2], btype) 是一个用于处理二进制数据的操作,其用法和含义如下
目录
在 Go 语言中,binary.LittleEndian.PutUint16(node[0:2], btype) 是一个用于处理二进制数据的操作,其用法和含义如下:#
代码结构解析#
binary.LittleEndian.PutUint16(node[0:2], btype)
binary** 包** 来自 Go 标准库的encoding/binary包,用于二进制数据的编码和解码。LittleEndian表示使用 小端字节序(Little-Endian)对数据进行编码。- 小端字节序:低位字节在前(例如
0x1234会存储为0x34 0x12)。 - 若需大端序,可使用
binary.BigEndian。
- 小端字节序:低位字节在前(例如
PutUint16** 方法** 将 16 位无符号整数(uint16)写入字节切片([]byte)。- 第一个参数:目标字节切片
node[0:2],必须至少有 2 字节容量(因为uint16占 2 字节)。 - 第二个参数:要写入的整数值
btype(类型需为uint16)。
- 第一个参数:目标字节切片
作用说明#
- 目的:将
btype的值以小端格式写入node切片的 前 2 个字节。 - 典型场景:
- 网络协议数据包封装
- 二进制文件格式写入
- 内存中结构化数据的二进制表示
示例#
package main
import (
"encoding/binary"
"fmt"
)
func main() {
var node = make([]byte, 2) // 创建一个 2 字节的切片
var btype uint16 = 0x1234 // 要写入的值
// 将 0x1234 以小端格式写入 node[0:2]
binary.LittleEndian.PutUint16(node[0:2], btype)
// 输出结果(小端序:低位在前)
fmt.Printf("%x\n", node) // 输出: 3412
}
关键注意事项#
- 切片长度
目标切片必须至少有 2 字节容量,否则会触发
panic。例如:
node := make([]byte, 1) // 长度不足,运行时会报错
binary.LittleEndian.PutUint16(node, 0x1234) // panic: runtime error: slice bounds out of range
2. **类型匹配** 写入的值必须是 **`uint16`** 类型。若变量类型不匹配,需显式转换: go
var btype int = 0x1234
binary.LittleEndian.PutUint16(node, uint16(btype)) // 强制转换
3. **字节序选择** 根据实际协议或格式要求选择字节序: go
binary.BigEndian.PutUint16(node, btype) // 大端序(高位在前)
<empty-block/> 4. 为什么输出是3412而不是1234 当使用 **`binary.LittleEndian.PutUint16`** 写入 **`0x1234`** 时:<br> 1. **数值分解** **`0x1234`** 是一个 16 位无符号整数(占 2 字节),可拆分为: - **高位字节**:**`0x12`**(对应二进制 **`00010010`**) - **低位字节**:**`0x34`**(对应二进制 **`00110100`**) 2. **小端序存储** - **低位字节在前**:**`0x34`** 存储在切片的前一个位置(索引 **`0`**) - **高位字节在后**:**`0x12`** 存储在切片的后一个位置(索引 **`1`**) 因此,写入后 **`node`** 切片的内容为: go
node = []byte{0x34, 0x12}
3. **格式化输出** 使用 **`fmt.Printf("%x\n", node)`** 时: - **`%x`** 会将每个字节转换为两位十六进制字符串。 - 按切片顺序依次输出字节:**`0x34`** → **`34`**,**`0x12`** → **`12`**,合并为 **`3412`**。 ### **对比实验:大端序(Big-Endian)的输出** 如果将代码改为大端序: go
binary.BigEndian.PutUint16(node[0:2], btype)
```
- 存储顺序:高位字节 0x12 在前(索引 0),低位字节 0x34 在后(索引 1)。
- 切片内容:node = []byte{0x12, 0x34}
- 输出结果:1234
---
### 内存布局可视化
| **字节序** | **内存地址(低 → 高)** | **十六进制表示** |
| Little | **`0x34`** **`0x12`** | **`3412`** |
| Big | **`0x12`** **`0x34`** | **`1234`** |
---
### **技术总结**
- **小端序**:低位字节存储在低地址,符合 x86/x64 架构的默认字节序。
- **大端序**:高位字节存储在低 地址,常见于网络协议(如 TCP/IP)和某些硬件架构。
- **实际应用**:
字节序的选择需与数据接收方一致。例如,网络传输通常使用大端序(网络字节序),而本地存储可能使用小端序。
如果尝试写入其他值(如 **`0xAABB`**),小端序的输出将是 **`BBAA`**,而大端序为 **`AABB`**。这种差异在跨平台或协议通信时必须特别注意!
<empty-block/>
常见用途#
- 序列化数据到字节流(如网络协议头、文件格式)
- 与硬件寄存器或底层系统 API 交互
- 优化内存布局(如手动控制结构体的二进制表示)