最直接方法是用 fmt.Printf("value: %v, type: %T\n", x, x);%T 显示运行时类型,接口 nil 时输出 ,结构体用 %+v 显字段名,%#v 输出 Go 字面量格式。

用 fmt.Printf 打印类型和值最直接
Go 没有像 Python 的 repr() 那样一键同时输出值+类型的内置函数,但 fmt.Printf 配合动词就能解决。最常用的是 %v(值)和 %T(类型),可以一起用:
fmt.Printf("value: %v, type: %T\n", x, x)
比如 x := 42 输出 value: 42, type: int;x := "hello" 输出 value: hello, type: string。注意 %T 显示的是底层类型名,对别名或自定义类型也准确,比如 type MyInt int,传 MyInt(1) 会显示 main.MyInt(包名前缀取决于定义位置)。
fmt.Sprintf 适合拼接后复用
如果不想直接打印,而是要构造带类型信息的字符串(比如日志、调试提示),用 fmt.Sprintf 更合适:
s := fmt.Sprintf("got %v (%T)", data, data)
常见错误是只写 fmt.Sprintf("%v %T", data) —— 少了一个参数,会 panic 报错 panic: runtime error: invalid memory address or nil pointer dereference 或更明确的 missing argument for verb T。务必确保每个动词都有对应参数。
结构体字段太多时,%+v 和 %#v 更有用
纯 %v 打印结构体只显示字段值,不带字段名;加 + 标志(%+v)会显式标出字段名,方便确认字段是否为空或零值:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
type User struct{ Name string; Age int }
u := User{Name: "Alice"}
fmt.Printf("%v\n", u) // {Alice 0}
fmt.Printf("%+v\n", u) // {Name:Alice Age:0}
%#v 则输出 Go 语法风格的字面量,能看清指针、切片底层数组等细节,适合深度调试:
fmt.Printf("%#v\n", []int{1,2}) // []int{1, 2}
fmt.Printf("%#v\n", &u) // &main.User{Name:"Alice", Age:0}
注意接口值和 nil 的类型显示差异
当变量是接口类型(如 interface{})时,%T 显示的是**运行时实际值的类型**,不是接口本身:
-
var i interface{} = 42→%T输出int,不是interface{} -
var i interface{}(未赋值)→%T输出,不是空接口类型名
这容易让人误判变量是否为 nil 接口。真要检查接口是否为 nil,得用 i == nil,不能依赖 %T 输出。另外,fmt 包对未导出字段(小写首字母)在结构体中默认不打印,即使用了 %+v 或 %#v —— 这是 Go 的反射规则,不是 bug。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










