Skip to content

Add cmpopts.FilterValue #277

Open
Open
@dsnet

Description

@dsnet

cmp.FilterValues expects a function of the signature func(T, T) bool where the function is called with values from both the left argument and the right argument.

I propose the addition of cmpopts.FilterValue that is semantically equivalent to:

func FilterValue[T any](f func(T) bool) cmp.Option {
    return cmp.FilterValues(func(x, y T) bool {
        return f(x) && f(y)
    })
}

The current cmp.FilterValues is more powerful as you can make a filtering decision based on information from both values, but most usages of it want the logical AND of a single-argument predicate function. In fact, all of the usages of cmp.FilterValues in cmpopts would prefer to use a single-argument predicate function. Examples:

  • func isEmpty(x, y interface{}) bool {
    vx, vy := reflect.ValueOf(x), reflect.ValueOf(y)
    return (x != nil && y != nil && vx.Type() == vy.Type()) &&
    (vx.Kind() == reflect.Slice || vx.Kind() == reflect.Map) &&
    (vx.Len() == 0 && vy.Len() == 0)
    }
  • func areRealF64s(x, y float64) bool {
    return !math.IsNaN(x) && !math.IsNaN(y) && !math.IsInf(x, 0) && !math.IsInf(y, 0)
    }
  • func areNaNsF64s(x, y float64) bool {
    return math.IsNaN(x) && math.IsNaN(y)
    }
  • func areNonZeroTimes(x, y time.Time) bool {
    return !x.IsZero() && !y.IsZero()
    }
  • func areConcreteErrors(x, y interface{}) bool {
    _, ok1 := x.(error)
    _, ok2 := y.(error)
    return ok1 && ok2
    }

Alternatively, we could modify cmp.FilterValues to also accept a function of the form func(T) bool where it effectively performs the AND of the predicate function applies to both arguments.

\cc @neild

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions