Go proposal: Compare IP subnets
Part of the Accepted! series, explaining the upcoming Go changes 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/8
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.
The proposal aims to 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/8 < 10.0.1.0/8
- 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.0.1.0/8"),
netip.MustParsePrefix("203.0.113.0/24"),
netip.MustParsePrefix("10.0.0.0/8"),
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/8
10.0.1.0/8
169.254.0.0/16
203.0.113.0/8
203.0.113.0/24
Further reading
★ Subscribe to keep up with new posts.