Skip to content

Instantly share code, notes, and snippets.

@juev
Created March 20, 2025 09:30
Show Gist options
  • Save juev/2fc23a96b136f8a38919c0dcfbe2c192 to your computer and use it in GitHub Desktop.
Save juev/2fc23a96b136f8a38919c0dcfbe2c192 to your computer and use it in GitHub Desktop.

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),
  )
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment