如何以双字结构格式打印Go语言string类型变量?
直观演示Go语言string类型的双字结构
Go语言的string类型本质是一个双字结构(64位系统下占16字节,由两个8字节字段组成):
- 第一个字段:指向底层字节数组的指针
- 第二个字段:字符串的实际长度(不含C风格的终止符
\0)
要直观展示这个结构,我们可以借助unsafe包直接读取string变量的内存布局,以下是适合教学的示例代码:
package main import ( "fmt" "unsafe" ) // 定义与Go runtime内部string结构完全匹配的结构体 type StringHeader struct { Data uintptr // 底层字节数组的内存地址 Len int // 字符串的长度 } func main() { // 定义一个字符串变量 a := "a string literal" // 将string变量的地址转换为自定义StringHeader的指针,直接读取底层结构 header := (*StringHeader)(unsafe.Pointer(&a)) fmt.Println("string变量的双字结构详情:") fmt.Printf("1. 底层字节数组地址: 0x%x\n", header.Data) fmt.Printf("2. 字符串长度: %d\n", header.Len) // 验证:通过地址取出底层字节数组,还原为字符串 fmt.Println("\n验证底层字节数组内容:") // 从地址生成字节切片 rawBytes := unsafe.Slice((*byte)(unsafe.Pointer(header.Data)), header.Len) fmt.Printf("原始字节数组: %v\n", rawBytes) fmt.Printf("还原后的字符串: %s\n", string(rawBytes)) }
输出解释
运行代码后会得到类似如下的结果(地址值会因运行环境不同而变化):
string变量的双字结构详情: 1. 底层字节数组地址: 0x109b3e0 2. 字符串长度: 16 验证底层字节数组内容: 原始字节数组: [97 32 115 116 114 105 110 103 32 108 105 116 101 114 97 108] 还原后的字符串: a string literal
注意事项
unsafe包用于绕过Go的类型安全机制,仅适合教学演示,实际业务代码中应避免使用- 32位系统下,
uintptr和int均为4字节,此时string的双字结构总大小为8字节,逻辑与64位系统一致
内容的提问来源于stack exchange,提问作者Picci
相关产品推荐
相关产品推荐

