func isNaN[T Ordered](x T) bool {
return x != x
}
+
+// Or returns the first of its arguments that is not equal to the zero value.
+// If no argument is non-zero, it returns the zero value.
+func Or[T comparable](vals ...T) T {
+ var zero T
+ for _, val := range vals {
+ if val != zero {
+ return val
+ }
+ }
+ return zero
+}
import (
"cmp"
+ "fmt"
"math"
"sort"
+ "slices"
"testing"
)
}
}
}
+
+func TestOr(t *testing.T) {
+ cases := []struct {
+ in []int
+ want int
+ }{
+ {nil, 0},
+ {[]int{0}, 0},
+ {[]int{1}, 1},
+ {[]int{0, 2}, 2},
+ {[]int{3, 0}, 3},
+ {[]int{4, 5}, 4},
+ {[]int{0, 6, 7}, 6},
+ }
+ for _, tc := range cases {
+ if got := cmp.Or(tc.in...); got != tc.want {
+ t.Errorf("cmp.Or(%v) = %v; want %v", tc.in, got, tc.want)
+ }
+ }
+}
+
+func ExampleOr() {
+ // Suppose we have some user input
+ // that may or may not be an empty string
+ userInput1 := ""
+ userInput2 := "some text"
+
+ fmt.Println(cmp.Or(userInput1, "default"))
+ fmt.Println(cmp.Or(userInput2, "default"))
+ fmt.Println(cmp.Or(userInput1, userInput2, "default"))
+ // Output:
+ // default
+ // some text
+ // some text
+}
+
+func ExampleOr_sort() {
+ type Order struct {
+ Product string
+ Customer string
+ Price float64
+ }
+ orders := []Order{
+ {"foo", "alice", 1.00},
+ {"bar", "bob", 3.00},
+ {"baz", "carol", 4.00},
+ {"foo", "alice", 2.00},
+ {"bar", "carol", 1.00},
+ {"foo", "bob", 4.00},
+ }
+ // Sort by customer first, product second, and last by higher price
+ slices.SortFunc(orders, func(a, b Order) int {
+ return cmp.Or(
+ cmp.Compare(a.Customer, b.Customer),
+ cmp.Compare(a.Product, b.Product),
+ cmp.Compare(b.Price, a.Price),
+ )
+ })
+ for _, order := range orders {
+ fmt.Printf("%s %s %.2f\n", order.Product, order.Customer, order.Price)
+ }
+
+ // Output:
+ // foo alice 2.00
+ // foo alice 1.00
+ // bar bob 3.00
+ // foo bob 4.00
+ // bar carol 1.00
+ // baz carol 4.00
+}