Go 语言学习笔记:指针与数据结构 (PHP 视角版)
核心心法:从 PHP 转 Go,最大的思维转变在于从“万能数组 (Array)”转向“严格类型 (Struct/Map)”以及理解“默认值传递”。
第一部分:指针 (Pointer)
1. 核心概念
Go 语言中的指针,本质上就是数据的内存地址。
&(取址):获取“门牌号”(地址)。*(解引用):拿着门牌号进屋,获取/修改里面的东西。
2. PHP 经验迁移
你的直觉非常准:Go 的指针 (*T) $\approx$ PHP 的引用 (&$v)。
- 共同目的:都是为了直接修改原始数据,而不是操作数据的副本 (Copy)。
- 区别:
- PHP:
foreach ($arr as &$v)是一种语法糖,PHP 帮你处理了地址。 - Go:必须显式地传递地址
&v,并在函数内显式操作*v。
- PHP:
3. 对象传递的差异 (这也是最大的坑)
| 场景 | PHP | Go |
|---|---|---|
| 传递对象 | 默认引用 (Class 实例默认就是引用) | 默认复制 (Struct 默认是值拷贝) |
| 如何修改 | 直接改 $obj->name |
必须传指针 func(u *User) |
4. 代码实战:如何正确修改数据
❌ 错误写法 (无效修改/只改了副本)
1 | func modify(u User) { // 没加 *,这是值传递,复制了一份 |
✅ 正确写法 (指针传递)
1 | func modify(u *User) { // 加了 *,这是传地址 |
⚠️ 逻辑陷阱
1 | func modify(u *User) { |
第二部分:数据结构 (Map vs Struct)
1. 为什么 Go 这么麻烦?
- PHP (Array):像一个大麻袋,不管 Key 是什么,Value 是什么,随便往里塞,还可以无限套娃。
- Go:像超市货架,必须分类。饮料区只能放饮料 (Type Safety)。
2. 什么时候用什么?(终极决策表)
| 数据特征 | PHP 习惯 | Go 最佳实践 | 典型例子 |
|---|---|---|---|
| 字段名固定 (已知结构) | Array ['name'=>'x'] |
Struct (结构体) | 用户信息、商品详情、登录参数 |
| Key 不固定,但 Value 类型一样 | Array | Map (字典) | 班级成绩单 name=>score、用户缓存 id=>User |
| 纯列表 (无 Key) | Array | Slice (切片) | [1, 2, 3] |
| 完全未知/乱七八糟 | Array | Map + Interface | 解析第三方未知的 JSON |
3. 嵌套 Struct (解决复杂数据)
不要试图用 Map 去模拟 PHP 的多维数组,会写出地狱代码。用 Struct 像搭积木一样嵌套。
1 | // 好的设计:清晰、有自动补全、类型安全 |
第三部分:黄金法则 (Cheat Sheet)
📌 关于指针
- 想在函数里修改外面的变量? $\rightarrow$ 传指针 (
*T)。 - 结构体很大,不想复制? $\rightarrow$ 传指针 (
*T)。 - 除此之外,优先用值传递。
📌 关于 Map vs Struct
问自己:“我在写代码时,能把 Key 的名字写死吗?”
- 能写死 (如 Name, Age) $\rightarrow$ 定义为 Struct 的字段。
- 不能写死 (如用户传来的 ID) $\rightarrow$ 定义为 Map 的 Key。
📌 关于 Interface
map[string]interface{}是 Go 里的“PHP 数组模式”。- 不到万不得已(处理未知 JSON),尽量少用,因为取值时需要断言,非常麻烦。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 野鹤的小窝!