3 回复
该值为 nil。但 Println 会将其表示为空映射然后输出。https://play.golang.org/p/Ey__aH1ZXtA 显示如果使用 Printed 和格式化代码 %#v,它会显示为 nil。
更多关于Golang中打印类型化nil的问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
映射和通道实际上是指向运行时类型的指针。当你初始化一个映射或通道时,它会创建一个指向运行时类型的指针,该指针引用的是 nil。当你打印它时,会显示非 nil 的指针值;但当你进行比较时,实际上比较的是它们所引用的值,也就是 nil。
是的,这种情况是正常的,符合Go语言的设计规范。你遇到的情况展示了Go语言中类型化nil(typed nil)的打印行为。
在Go中,当一个接口值持有具体类型的nil值时,接口本身并不等于nil。这是因为接口包含两个组件:类型信息和值信息。即使值为nil,只要类型信息存在,接口就不等于nil。
在你的示例中:
package main
import "fmt"
type MyError struct{}
func (e *MyError) Error() string {
return "my error"
}
func main() {
var err *MyError
fmt.Printf("err: %v\n", err)
fmt.Printf("err == nil: %t\n", err == nil)
var iface error = err
fmt.Printf("iface: %v\n", iface)
fmt.Printf("iface == nil: %t\n", iface == nil)
}
输出结果是:
err: <nil>
err == nil: true
iface: <nil>
iface == nil: false
这里的关键点:
err是*MyError类型的nil指针,打印为<nil>iface是error接口类型,它持有*MyError类型的nil值,所以打印为<nil>但iface == nil返回false
这种设计是为了保持类型安全。当你需要检查接口是否为nil时,应该显式地将其与nil比较:
if iface != nil {
// 处理非nil情况
}
或者使用反射来检查:
import "reflect"
if iface == nil || reflect.ValueOf(iface).IsNil() {
// 处理nil情况
}
这是Go语言中一个常见的陷阱,很多开发者都会遇到。理解接口的内部结构(类型+值)对于正确处理这种情况很重要。

