netip.ParseAddr 更可靠,因其返回不可变、类型安全的 netip.Addr,避免 IPv4/IPv6 隐式转换、零值歧义及静默截断;解析失败直接报错,且无堆分配、性能更优。

netip.ParseAddr 为什么比 net.ParseIP 更可靠
因为 net.ParseIP 返回 *net.IP,底层是切片别名,零值不明确、可变、且 IPv4/IPv6 混用时容易隐式转换(比如 "127.0.0.1" 解析后调 .To4() 得到 [4]byte,但对 IPv6 地址调 .To4() 返回 nil,不报错也不提示);而 netip.ParseAddr 返回不可变的 netip.Addr,类型安全,IPv4 和 IPv6 无法互相隐式转换,解析失败直接返回 error。
常见错误现象:net.ParseIP("::1").To4() == nil 看似合理,但后续如果没判空就 panic;或者把 net.ParseIP("192.168.1.1") 当作 IPv6 传给只接受 IPv6 的函数,运行时才出问题。
-
netip.ParseAddr输入非法字符串(如"127.0.0.1:80")直接返回 error,不静默截断 - 它不接受端口、前缀长度、主机名——这些必须用
netip.ParseAddrPort或netip.ParsePrefix - 性能上,
netip.Addr是值类型,无堆分配,比*net.IP更轻量
解析带端口的地址用 netip.ParseAddrPort 而不是拼接字符串
很多人习惯先 net.ParseIP 再手动拼 ":port",再丢给 net.Listen,但这在 IPv6 下会出错:IPv6 地址本身含冒号,必须用方括号包裹,比如 "[::1]:8080"。手拼极易漏括号,导致 listen tcp: address [::1]:8080: too many colons in address。
netip.ParseAddrPort 自动处理这个细节:输入 "::1:8080" 或 "[::1]:8080" 都能正确解析,输出 netip.AddrPort 值,调 .Addr() 和 .Port() 分离干净。
立即学习“go语言免费学习笔记(深入)”;
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 输入格式支持:IPv4
"127.0.0.1:3000"、IPv6"::1:3000"、带括号 IPv6"[::1]:3000" - 不支持主机名(如
"localhost:3000"),得先 DNS 解析再传 IP - 端口为 0 是合法的(表示系统自动分配),
netip.AddrPort会保留它
判断地址族别别用字符串匹配,用 Addr.Is4() / Addr.Is6()
有人写 strings.Contains(ip.String(), ":") 判 IPv6,这在 IPv4-mapped IPv6(如 ::ffff:192.168.1.1)下失效;也有人用 len(ip) == 16,但 net.IP 是切片,长度不等于地址族。
netip.Addr 提供了明确的族判断方法:addr.Is4() 和 addr.Is6(),语义清晰、无歧义、零开销。
-
netip.MustParseAddr("::1").Is6()→true -
netip.MustParseAddr("127.0.0.1").Is4()→true -
netip.MustParseAddr("::ffff:192.0.2.1").Is4()→false(它是 IPv6 地址,不是 IPv4-mapped 的“伪 IPv4”)
netip 不兼容老代码,迁移时注意 Addr 不能直接传给 net.Listener
net.Listen、net.Dial 等函数只认 string 地址(如 "127.0.0.1:8080")或 *net.IP,不接受 netip.Addr 或 netip.AddrPort。不能直接替换,必须显式转回字符串。
转法很简单:addr.String()、addrPort.String() 即可,它们输出标准格式(IPv6 自动加方括号)。但要注意:如果你原来依赖 net.IP 的可变性(比如反复修改同一块内存),netip.Addr 的不可变性会让这类逻辑失效。
-
netip.MustParseAddr("::1").String()→"::1" -
netip.MustParseAddrPort("[::1]:8080").String()→"[::1]:8080" - 别用
fmt.Sprintf("%v", addr),它不保证格式稳定
最易被忽略的是:netip 的地址比较用 ==,而 net.IP 必须用 bytes.Equal;混用会导致逻辑错误却不易察觉。

















