
本文深入解析Go语言中对字符串指针进行解引用(course)后直接赋值的底层机制,阐明`course = "Docker Extended"`为何合法且有效——本质是通过指针修改原变量所指向的内存位置中的字符串值。
本文深入解析go语言中对字符串指针进行解引用(*course)后直接赋值的底层机制,阐明*course = "docker extended"为何合法且有效——本质是通过指针修改原变量所指向的内存位置中的字符串值。
在Go中,字符串虽为不可变(immutable)类型,但字符串变量本身是可变的——它本质上是一个包含两个字段的结构体:指向底层字节数组的指针(data)和长度(len)。因此,字符串变量的值(即该结构体)可以被整体替换。
当执行 course := "Docker Deep Dive" 时,Go在栈上分配一个字符串头(string header),其中data指向只读的字符串字面量内存区域,len为16。而 &course 获取的是该字符串头在栈上的地址;*course 则是对该地址的解引用,得到的是可寻址的字符串变量本身(而非其内容不可变的底层字节),因此支持赋值操作:
func changeCourse(course *string) {
fmt.Println(course) // 输出类似 0xc000010230(栈上字符串头的地址)
fmt.Println(*course) // 输出 "Docker Deep Dive"
*course = "Docker Extended" // ✅ 合法:将新的字符串头(新data指针 + 新len)写入原地址
fmt.Println(*course) // 输出 "Docker Extended"
}
⚠️ 注意事项:
-
*course = ...修改的是course所指向的字符串头,不是修改原字符串字面量内容(后者仍不可变); - 该操作等价于
course = &("Docker Extended")的效果,但语法更直接; - 若指针为
nil(如var p *string未初始化),执行*p = "x"将触发 panic:invalid memory address or nil pointer dereference; - 此机制适用于所有可寻址的变量类型(如
*int、*struct{}),是Go指针操作的基础范式。
总结:*course = "Docker Extended" 并非“修改字符串内容”,而是“用一个新的字符串值(含新地址与新长度)覆盖原字符串变量在内存中的二进制表示”。理解这一点,是掌握Go内存模型与指针语义的关键一步。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











