Go-фича: Сравнение IP-подсетей
Часть серии Принято! В ней простыми словами объясняются новые фичи Go.
Сравнивать префиксы IP-адресов так же, как это делает IANA (администрация адресного пространства интернета).
Версия 1.26 • Станд. библиотека • Мелочь
Что
Префикс IP-адреса задает определенную подсеть. Обычно такие префиксы записывают в формате CIDR:
10.0.0.0/8
127.0.0.0/8
169.254.0.0/16
203.0.113.0/24
В Go IP-префикс представлен типом netip.Prefix.
Новый метод Prefix.Compare позволяет сравнить два IP-префикса, что упрощает их сортировку — не придется писать свой код сравнения. Порядок сравнения совпадает с реализацией в Python и с порядком, который использует IANA.
Зачем
Когда команда Go изначально разрабатывала тип IP-подсети (net/netip.Prefix), они решили не добавлять метод Compare, потому что не было общепринятого способа упорядочивать такие значения.
Из-за этого, если разработчику нужно отсортировать IP-подсети — например, чтобы организовать таблицы маршрутизации или провести тесты — приходится писать собственную логику сравнения. Это приводит к повторяющемуся коду, чреватому ошибками.
Чтобы улучшить ситуацию, в Go добавят стандартный способ сравнения IP-префиксов. Это должно уменьшить количество шаблонного кода и помочь программам сортировать IP-подсети одинаково.
Подробности
Добавить метод Compare в тип netip.Prefix:
// Compare возвращает целое число - результат сравнения двух префиксов.
// Результат будет 0, если p == p2, -1, если p < p2, и +1, если p > p2.
func (p Prefix) Compare(p2 Prefix) int
Вот как Compare сравнивает префиксы:
- Сначала по корректности (некорректные идут перед корректными).
- Потом по семейству адресов (IPv4 перед IPv6).
10.0.0.0/8 < ::/8 - Потом по маскированному IP-адресу (IP подсети).
10.0.0.0/8 < 10.0.1.0/8 - Потом по длине префикса.
10.0.0.0/8 < 10.0.0.0/16 - Потом по немаскированному адресу (оригинальный IP).
10.0.0.0/8 < 10.0.0.1/8
Это тот же порядок, что использует netaddr.IPNetwork в Python и IANA.
Пример
Отсортировать список IP-префиксов:
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
Ссылки
★ Подписывайтесь на канал и проходите курсы.