我有映射与键作为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作为映射密钥类型吗?
甲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.String和net.ParseIP函数进行转换:
x.MapOfValues[ip.String()] = v
for k, v := range x.MapOfValues {
ip := net.ParseIP(k)
...
}
Run Code Online (Sandbox Code Playgroud)
从 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)