Go语言中为什么不能比较net.Addr

最近,我试图理解并学习为什么在Go语言中无法比较两个相同的net.Addr。根据我在一篇文章中的研究,如果两个接口具有相同的底层类型,并且该类型是可比较的,那么它们应该可以进行比较。在我的示例中,底层类型是net.UDPAddr,它是一个结构体,包含一个字符串、一个整数和一个net.IP(net.IP是[]byte的类型别名)。

那么,为什么我无法比较它们?是因为切片IP不可比较吗?尽管它的类型、长度和内容都是相同的?

让我们来看一个示例:

https://go.dev/play/p/dIzRCTwBA4P

您的示例比较了两次对net.ResolveUDPAddr的调用返回的值。然而,如果您考虑一下函数签名:

goCopy codefunc ResolveUDPAddr(network, address string) (*UDPAddr, error)

您会注意到,您实际上正在比较两个指针;这些指针是可比较的,但不会相等(您比较的是指针,而不是它指向的值)。

根据Go语言规范:

  • 如果结构体类型的所有字段类型都是可比较的,则结构体类型是可比较的。
  • 切片、映射和函数类型不可比较。但是,作为特殊情况,切片、映射或函数值可以与预声明的标识符nil进行比较。

net.UDPAddr包含一个net.IP,而net.IP是[]byte类型,因此不可比较。