net.IP作为golang中的映射密钥类型?

Ron*_*oda 5 go

我有映射与键作为net.IP和值作为渠道。但是我收到一个奇怪的编译时错误(无效的映射键类型)

17 type UdpServer struct {
18     ListenPort int
19
20     ConnRef *net.UDPConn
21     Log_ref *Logger
22     MapOfValues map[net.IP]chan string
23 }


$ go build c-manager.go
cmanager/c-udp_server.go:22:14: invalid map key type net.IP

$ go version
  go version go1.10.2 linux/amd64
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我们不能将net.IP作为映射密钥类型吗?

Cer*_*món 5

net.IP是片段类型。由于切片是可变的,因此它们不能用作地图键。使用字符串作为键类型:

MapOfValues map[string]chan string
Run Code Online (Sandbox Code Playgroud)

使用类型转换将net.IP转换为字符串并返回。使用IP.To16将地址标准化为16字节表示形式。

x.MapOfValues[string(ip.To16())] = v

for k, v := range x.MapOfValues {
   ip := net.IP(k) // convert string to net.IP
   ...
}
Run Code Online (Sandbox Code Playgroud)

如果希望键是可打印的,请使用IP.Stringnet.ParseIP函数进行转换:

x.MapOfValues[ip.String()] = v

for k, v := range x.MapOfValues {
   ip := net.ParseIP(k) 
   ...
}
Run Code Online (Sandbox Code Playgroud)


bla*_*een 5

从 Go 1.18 开始,您现在可以netip.Addr直接用作地图键。这种新 IP 类型声明的意图之一就是支持==!=运算符,因此允许用作映射键。

Addr 表示 IPv4 或 IPv6 地址(有或没有范围寻址区域),类似于 net.IP 或 net.IPAddr。

与 net.IP 或 net.IPAddr 不同,Addr 是可比较的值类型(它支持 == 并且可以是映射键)并且是不可变的。

所以现在您可以将结构字段声明为:

MapOfValues map[netip.Addr]chan string
Run Code Online (Sandbox Code Playgroud)