当使用 `fmt.printf` 无法递归解引用多层指针(如 `*[]*x`)时,标准库不支持自动展开,需借助第三方调试工具 `go-spew` 实现深度、可读性强的值打印。
在 Go 单元测试或调试场景中,经常需要完整查看嵌套指针结构的实际内容——例如 *[]*X 这类“指向切片指针的指针”,而 fmt.Printf("%#v", v) 仅显示地址(如 (*[]*main.X)(0x10436180)),无法反映 X 结构体字段的真实值。这是因为 fmt 包的设计原则是不主动解引用指针(避免副作用与性能开销),它忠实地按值类型输出,对指针只展示地址。
此时,标准库 fmt 的 %v、%#v、%+v 等动词均无法满足需求。官方并未提供类似 “递归解引用” 的 flag(如 %r 或 --deep),因此必须引入专为调试设计的工具。
推荐使用 github.com/davecgh/go-spew 库,它专为深度、安全、可配置的 Go 值打印而生,支持:

以原示例为例,只需两步即可获得完整结构:
go get github.com/davecgh/go-spew/spew
修改代码如下:
package main
import (
"fmt"
"github.com/davecgh/go-spew/spew"
)
func main() {
type X struct {
desc string
}
type test struct {
in *[]*X
want *[]*X
}
test1 := test{
in: &[]*X{
&X{desc: "first"},
&X{desc: "second"},
&X{desc: "third"},
},
}
fmt.Println("Using fmt.Printf:")
fmt.Printf("%#v\n", test1)
fmt.Println("\nUsing spew.Dump:")
spew.Dump(test1)
}输出效果(关键部分):
(main.test) {
in: (*[]*main.X)(0xc000010240)({
(*main.X)(0xc000010250)({
desc: (string) "first"
}),
(*main.X)(0xc000010260)({
desc: (string) "second"
}),
(*main.X)(0xc000010270)({
desc: (string) "third"
})
}),
want: (*[]*main.X)()
} ✅ 优势总结:
⚠️ 注意事项:
总之,面对深层指针结构的调试需求,go-spew 是当前最成熟、最可靠的解决方案——它填补了 fmt 包在深度可视化上的空白,让测试失败时的诊断变得直观而高效。