reflect: implement and test Value.Comparable

This commit is contained in:
Damian Gryski
2023-03-24 12:19:33 -07:00
committed by Ron Evans
parent a11f2436e3
commit d4bdd836bc
3 changed files with 40 additions and 0 deletions
+4
View File
@@ -8105,6 +8105,8 @@ func TestValue_Len(t *testing.T) {
}
}
*/
func TestValue_Comparable(t *testing.T) {
var a int
var s []int
@@ -8286,6 +8288,8 @@ func TestValue_Comparable(t *testing.T) {
}
}
/*
type ValueEqualTest struct {
v, u any
eq bool
+2
View File
@@ -958,6 +958,8 @@ func (t *rawType) Implements(u Type) bool {
// Comparable returns whether values of this type can be compared to each other.
func (t *rawType) Comparable() bool {
switch t.Kind() {
case Invalid:
return false
case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
return true
case Float32, Float64, Complex64, Complex128:
+34
View File
@@ -217,6 +217,40 @@ func (v Value) CanAddr() bool {
return v.flags&(valueFlagIndirect) == valueFlagIndirect
}
func (v Value) Comparable() bool {
k := v.Kind()
switch k {
case Invalid:
return false
case Array:
switch v.Type().Elem().Kind() {
case Interface, Array, Struct:
for i := 0; i < v.Type().Len(); i++ {
if !v.Index(i).Comparable() {
return false
}
}
return true
}
return v.Type().Comparable()
case Interface:
return v.Elem().Comparable()
case Struct:
for i := 0; i < v.NumField(); i++ {
if !v.Field(i).Comparable() {
return false
}
}
return true
default:
return v.Type().Comparable()
}
}
func (v Value) Addr() Value {
if !v.CanAddr() {
panic("reflect.Value.Addr of unaddressable value")