hex.EncodeToString只接受[]byte参数,传string会编译报错;需显式转换为[]byte(s),但会拷贝内存;输出恒为小写,大写需strings.ToUpper;非数字类型不可用fmt.Sprintf("%X")替代;性能敏感时宜用hex.Encode预分配或hex.NewEncoder流式处理。

encoding/hex.EncodeToString 是 Go 标准库中把字节切片转成小写十六进制字符串最直接的方式,它安全、无依赖、无需额外初始化。
为什么不能直接传字符串给 EncodeToString
这个函数只接受 []byte 类型参数。如果你传入 string,会编译报错:cannot use s (type string) as type []byte in argument to hex.EncodeToString。Go 中字符串是只读的,必须显式转换。
- 正确做法:用
[]byte(s)转换,例如hex.EncodeToString([]byte("hello")) - 注意:这会拷贝底层数组,对超长字符串有内存开销
- 如果原始数据已经是
[]byte(比如从io.Read读出),跳过转换更高效
EncodeToString 输出永远是小写,没法改
标准库没有提供大小写开关,输出固定为小写字母 a–f。如果你需要大写,得自己映射或用 strings.ToUpper:
src := []byte("Go")
s := hex.EncodeToString(src) // "676f"
s = strings.ToUpper(s) // "676F"
- 别试图用
fmt.Sprintf("%X", ...)替代——它不支持任意字节,只对数字/整数类型有效 - 也别用
hex.Dump,那是带偏移和 ASCII 的调试格式,不是纯 hex 字符串
性能敏感时,考虑复用 hex.Encoder 或预分配
频繁调用 EncodeToString(比如每秒上万次)会产生较多短生命周期的字符串和中间切片。这时可选:
- 用
hex.Encode配合预分配的[]byte目标缓冲区,避免重复分配 - 对流式数据(如 HTTP body、文件读取),用
hex.NewEncoder(io.Writer)直接写入,减少中间字符串 -
EncodeToString内部其实也是先调Encode再转string,所以它本质是 convenience wrapper
真正容易被忽略的是:它不校验输入字节内容——哪怕你传入含控制字符或 UTF-8 多字节的 []byte,它照样编码,只是按字节逐个转。所以确保你传进去的确实是想表达的二进制数据,而不是误把文本编码逻辑混进来。


















