Введение
Добро пожаловать в подробный обзор нового пакета cmp в Go версии 1.21. В этом посте мы рассмотрим, как эти обновления оптимизируют сравнение значений, делая ваш код более эффективным и интуитивно понятным. Оставайтесь с нами, чтобы узнать об улучшениях, которые Go 1.21 привносит в пакет cmp, и о том, как они могут улучшить ваш опыт программирования.
Первым шагом является импорт пакета cmp.
import ( "cmp" )
Мы можем использовать этот пакет для сравнения. Он предоставляет два метода: Сравнить и Меньше.
Сравнивать
Метод «Сравнить» сравнивает 2 значения:
- если первое значение меньше второго значения, метод вернет -1
- если оба значения равны, метод вернет 0
- если первое значение больше второго значения, метод вернет +1
func Compare[T Ordered](x, y T) int // in this case, the result will be +1 cmp.Compare(3,2)
Меньше
Мы можем использовать этот метод, чтобы проверить, меньше ли первое значение второго значения. В этом случае результат будет истинным; в противном случае оно будет ложным.
(если оба значения равны, результат будет ложным)
func Less[T Ordered](x, y T) bool // in this case, the result will be true cmp.Less(1,2)
Ценности Нан
Мы не можем выполнять сравнения между значениями NaN:
NaN < NaN // false NaN > NaN // false NaN == NaN // false
Однако интересно то, что с помощью этих методов мы можем работать со значениями NaN. В этом случае:
- NaN всегда меньше любого значения, отличного от NaN.
- NaN считается равным значению NaN.
Перейти Исходный код
Ниже приведен исходный код для Сравнить.
func Compare[T Ordered](x, y T) int { xNaN := isNaN(x) yNaN := isNaN(y) if xNaN && yNaN { return 0 } if xNaN || x < y { return -1 } if yNaN || x > y { return +1 } return 0 }
Существует частная функция isNaN, которая проверяет, является ли значение NaN.
func isNaN[T Ordered](x T) bool { return x != x }
Когда мы сравниваем, если NaN равен NaN, результат всегда будет false. Аналогично, если мы сравним, что какое-то значение NaN отличается от другого значения NaN, результат будет true.
То же самое относится и к методу Less; они используют эту частную функцию для сравнения.
func Less[T Ordered](x, y T) bool { return (isNaN(x) && !isNaN(y)) || x < y }
Исходный код: https://cs.opensource.google/go/go/+/refs/tags/go1.21.0:src/cmp/cmp.go
Заказанный тип
В версии Go 1.21 мы можем использовать Ordered Type вместо внешнего пакета constraints для проведения сравнений в Generics (упорядоченные сравнения).
Например, в версиях до 1.21 мы использовали:
import ( "fmt" "golang.org/x/exp/constraints" ) func main(){ oldOrderedValues(2, 4) } func oldOrderedValues[N constraints.Ordered](v1, v2 N){ fmt.Println(v1, v2) fmt.Println(v1 !=v2) fmt.Println(v1 < v2) fmt.Println(v1 > v2) }
Выход:
2 4 true true false
однако в go 1.21 мы можем использовать:
import ( "cmp" "fmt" ) func main(){ orderedValues(2,4) } func orderedValues[N cmp.Ordered](v1, v2 N){ fmt.Println(v1, v2) fmt.Println(v1 !=v2) fmt.Println(v1 < v2) fmt.Println(v1 > v2) }
Выход:
2 4 true true false
Заключение
Подводя итог: с помощью пакета cmp мы можем выполнять сравнения, и он очень хорошо работает со значениями NaN. Кроме того, мы можем использовать тип Ordered вместо внешнего пакета ограничений для выполнения сравнений в универсальных шаблонах.
ресурс: blog_go_v21_cmp
блог: Би Блогит