ge
Returns the boolean truth of arg1 >= arg2
-These functions work on basic types only (or named basic types,
-such as "type Celsius float32"). They implement the Go rules for
-comparison of values, except that size and exact type are ignored,
-so any integer value may be compared with any other integer value,
-any unsigned integer value may be compared with any other unsigned
-integer value, and so on. However, as usual, one may not compare
-an int with a float32 and so on.
+For simpler multi-way equality tests, eq (only) accepts two or more
+arguments and compares the second and subsequent to the first,
+returning in effect
+
+ arg1==arg2 || arg1==arg3 || arg1==arg4 ...
+
+(Unlike with || in Go, however, eq is a function call and all the
+arguments will be evaluated.)
+
+The comparison functions work on basic types only (or named basic
+types, such as "type Celsius float32"). They implement the Go rules
+for comparison of values, except that size and exact type are
+ignored, so any integer value may be compared with any other integer
+value, any unsigned integer value may be compared with any other
+unsigned integer value, and so on. However, as usual, one may not
+compare an int with a float32 and so on.
Associated templates
{"eq `xy` `xyz`", "false", true},
{"eq .Xuint .Xuint", "true", true},
{"eq .Xuint .Yuint", "false", true},
+ {"eq 3 4 5 6 3", "true", true},
+ {"eq 3 4 5 6 7", "false", true},
{"ne true true", "false", true},
{"ne true false", "true", true},
{"ne 1+2i 1+2i", "false", true},
{"ge .Xuint .Yuint", "false", true},
{"ge .Yuint .Xuint", "true", true},
// Errors
- {"eq 3 4 5", "", false}, // Too many arguments.
{"eq `xy` 1", "", false}, // Different types.
{"lt true true", "", false}, // Unordered types.
{"lt 1+0i 1+0i", "", false}, // Unordered types.
continue
}
if !test.ok && err == nil {
- t.Errorf("%s did not error")
+ t.Errorf("%s did not error", test.expr)
continue
}
if b.String() != test.truth {
var (
errBadComparisonType = errors.New("invalid type for comparison")
errBadComparison = errors.New("incompatible types for comparison")
+ errNoComparison = errors.New("missing argument for comparison")
)
type kind int
return invalidKind, errBadComparisonType
}
-// eq evaluates the comparison a == b.
-func eq(arg1, arg2 interface{}) (bool, error) {
+// eq evaluates the comparison a == b || a == c || ...
+func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
v1 := reflect.ValueOf(arg1)
k1, err := basicKind(v1)
if err != nil {
return false, err
}
- v2 := reflect.ValueOf(arg2)
- k2, err := basicKind(v2)
- if err != nil {
- return false, err
+ if len(arg2) == 0 {
+ return false, errNoComparison
}
- if k1 != k2 {
- return false, errBadComparison
- }
- truth := false
- switch k1 {
- case boolKind:
- truth = v1.Bool() == v2.Bool()
- case complexKind:
- truth = v1.Complex() == v2.Complex()
- case floatKind:
- truth = v1.Float() == v2.Float()
- case intKind:
- truth = v1.Int() == v2.Int()
- case stringKind:
- truth = v1.String() == v2.String()
- case uintKind:
- truth = v1.Uint() == v2.Uint()
- default:
- panic("invalid kind")
+ for _, arg := range arg2 {
+ v2 := reflect.ValueOf(arg)
+ k2, err := basicKind(v2)
+ if err != nil {
+ return false, err
+ }
+ if k1 != k2 {
+ return false, errBadComparison
+ }
+ truth := false
+ switch k1 {
+ case boolKind:
+ truth = v1.Bool() == v2.Bool()
+ case complexKind:
+ truth = v1.Complex() == v2.Complex()
+ case floatKind:
+ truth = v1.Float() == v2.Float()
+ case intKind:
+ truth = v1.Int() == v2.Int()
+ case stringKind:
+ truth = v1.String() == v2.String()
+ case uintKind:
+ truth = v1.Uint() == v2.Uint()
+ default:
+ panic("invalid kind")
+ }
+ if truth {
+ return true, nil
+ }
}
- return truth, nil
+ return false, nil
}
// ne evaluates the comparison a != b.