User Tools

Site Tools


golang:cmpor

cmp.Or

источник

// 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
}

How do you use it?

The primary use for cmp.Or is for taking strings and returning the first one that isn’t blank. For example, searching public open source Go repositories, I found a lot of code online that tries to fetch an environmental variable but return a default value if it’s blank. With cmp.Or, this would look like cmp.Or(os.Getenv(“SOME_VARIABLE”), “default”).

Here are a handful of actual uses from a real codebase of mine:

body := cmp.Or(page.Body, rawContent)
name := cmp.Or(jwt.Username(), "Almanack")
credits = append(credits, cmp.Or(credit.Name, credit.Byline))
metadata.InternalID = cmp.Or(
    xhtml.InnerText(rows.Value("slug")),
    xhtml.InnerText(rows.Value("internal id")),
    metadata.InternalID,
)
scope.SetTag("username", cmp.Or(userinfo.Username(), "anonymous"))
currentUl = cmp.Or(
    xhtml.Closest(currentUl.Parent, xhtml.WithAtom(atom.Ul)),
    currentUl,
)

The other major use for cmp.Or is to use with cmp.Compare to create multipart comparisons:

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),
	)
})
golang/cmpor.txt · Last modified: 2024/04/30 11:53 by Denis Evsyukov