
go 的 `json.unmarshal` 要求传入指向目标变量的指针,否则会因接收非指针值而静默失败(实际返回错误但被忽略),导致反序列化无效果。
在 Go 中,encoding/json.Unmarshal 函数的设计原则是:必须传入目标变量的地址(即指针),以便函数能直接修改该变量的内存内容。若传入非指针值(如 unmarshalled 本身),Unmarshal 会立即返回错误 json: Unmarshal(non-pointer map[string]string),但因代码中使用了 _ = json.Unmarshal(...) 忽略了错误,程序看似“运行成功”,实则 unmarshalled 仍为零值(空 map)。
以下是修复后的完整示例:
package main
import (
"encoding/json"
"fmt"
)
func main() {
m := map[string]string{"name": "Test"}
j, err := json.Marshal(m)
if err != nil {
panic(err) // 或合理处理错误
}
fmt.Println("JSON:", string(j)) // 输出: {"name":"Test"}
var unmarshalled map[string]string
err = json.Unmarshal(j, &unmarshalled) // ✅ 关键:传入 &unmarshalled
if err != nil {
panic(err)
}
fmt.Printf("Unmarshalled: %+v\n", unmarshalled) // 输出: map[name:Test]
}⚠️ 注意事项:
- 永远检查 Unmarshal 的返回错误:忽略错误是调试 JSON 问题的最大陷阱;
- 切片、结构体、map 等复合类型都需传指针(如 &mySlice, &myStruct, &myMap);
- 若目标变量为 nil 指针(如 var p *map[string]string),Unmarshal 会自动分配新值;但此处 unmarshalled 是已声明的变量,只需取其地址即可;
- 对于结构体字段,确保字段名首字母大写(导出)且有对应 JSON tag(如 json:"name"),否则无法反序列化。
总结:Go 的 JSON 反序列化不是“赋值操作”,而是“内存填充操作”,因此指针是必需的契约。养成 err != nil 检查习惯,并始终传递变量地址,可避免 90% 以上的反序列化失效问题。










