Go feature: Compare IP subnets
Part of the Accepted! series: Go proposals and features explained in simple terms.
Compare IP address prefixes the same way IANA does.
Ver. 1.26 • Stdlib • Low impact
Summary
An IP address prefix represents a IP subnet. These prefixes are usually written in CIDR notation:
10.0.0.0/16
127.0.0.0/8
169.254.0.0/16
203.0.113.0/24
In Go, an IP prefix is represented by the netip.Prefix type.
The new Prefix.Compare method lets you compare two IP prefixes, making it easy to sort them without having to write your own comparison code. The imposed order matches both Python's implementation and the assumed order from IANA.
Motivation
When the Go team initially designed the IP subnet type (net/netip.Prefix), they chose not to add a Compare method because there wasn't a widely accepted way to order these values.
Because of this, if a developer needs to sort IP subnets — for example, to organize routing tables or run tests — they have to write their own comparison logic. This results in repetitive and error-prone code.
To make things better, we can provide a standard way to compare IP prefixes. This should reduce boilerplate code and help programs sort IP subnets consistently.
Description
Add the Compare method to the netip.Prefix type:
// Compare returns an integer comparing two prefixes.
// The result will be 0 if p == p2, -1 if p < p2, and +1 if p > p2.
func (p Prefix) Compare(p2 Prefix) int
Compare orders two prefixes as follows:
- First by validity (invalid before valid).
- Then by address family (IPv4 before IPv6).
10.0.0.0/8 < ::/8 - Then by masked IP address (network IP).
10.0.0.0/16 < 10.1.0.0/16 - Then by prefix length.
10.0.0.0/8 < 10.0.0.0/16 - Then by unmasked address (original IP).
10.0.0.0/8 < 10.0.0.1/8
This follows the same order as Python's netaddr.IPNetwork and the standard IANA convention.
Example
Sort a list of IP prefixes:
prefixes := []netip.Prefix{
netip.MustParsePrefix("10.1.0.0/16"),
netip.MustParsePrefix("203.0.113.0/24"),
netip.MustParsePrefix("10.0.0.0/16"),
netip.MustParsePrefix("169.254.0.0/16"),
netip.MustParsePrefix("203.0.113.0/8"),
}
slices.SortFunc(prefixes, func(a, b netip.Prefix) int {
return a.Compare(b)
})
for _, p := range prefixes {
fmt.Println(p.String())
}
10.0.0.0/16
10.1.0.0/16
169.254.0.0/16
203.0.113.0/8
203.0.113.0/24
Links & Credits
𝗣 61642 👥 Dave Anderson, Karl Gaissmaier
𝗖𝗟 700355 👥 Dave Anderson, database64128
★ Subscribe to keep up with new posts.