diff options
-rw-r--r-- | src/reflect/type.go | 38 | ||||
-rw-r--r-- | testdata/reflect.go | 3 | ||||
-rw-r--r-- | testdata/reflect.txt | 36 |
3 files changed, 59 insertions, 18 deletions
diff --git a/src/reflect/type.go b/src/reflect/type.go index d537f40e0..b5142ca63 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -398,6 +398,44 @@ func (t Type) AssignableTo(u Type) bool { return false } +// Comparable returns whether values of this type can be compared to each other. +func (t Type) Comparable() bool { + switch t.Kind() { + case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr: + return true + case Float32, Float64, Complex64, Complex128: + return true + case String: + return true + case UnsafePointer: + return true + case Chan: + return true + case Interface: + return true + case Ptr: + return true + case Slice: + return false + case Array: + return t.Elem().Comparable() + case Func: + return false + case Map: + return false + case Struct: + numField := t.NumField() + for i := 0; i < numField; i++ { + if !t.Field(i).Type.Comparable() { + return false + } + } + return true + default: + panic(TypeError{"Comparable"}) + } +} + // A StructField describes a single field in a struct. type StructField struct { // Name indicates the field name. diff --git a/testdata/reflect.go b/testdata/reflect.go index 8377f95c9..4fe8cbb33 100644 --- a/testdata/reflect.go +++ b/testdata/reflect.go @@ -268,6 +268,9 @@ func showValue(rv reflect.Value, indent string) { if rv.CanSet() { print(" settable=", rv.CanSet()) } + if !rt.Comparable() { + print(" comparable=false") + } println() switch rt.Kind() { case reflect.Bool: diff --git a/testdata/reflect.txt b/testdata/reflect.txt index ab3232bef..8bb878773 100644 --- a/testdata/reflect.txt +++ b/testdata/reflect.txt @@ -90,7 +90,7 @@ reflect type: ptr nil: false reflect type: int settable=true int: 0 -reflect type: slice +reflect type: slice comparable=false slice: uint8 3 3 pointer: true nil: false @@ -103,7 +103,7 @@ reflect type: slice indexing: 2 reflect type: uint8 settable=true uint: 3 -reflect type: slice +reflect type: slice comparable=false slice: uint8 2 5 pointer: true nil: false @@ -113,7 +113,7 @@ reflect type: slice indexing: 1 reflect type: uint8 settable=true uint: 0 -reflect type: slice +reflect type: slice comparable=false slice: int32 2 2 pointer: true nil: false @@ -123,7 +123,7 @@ reflect type: slice indexing: 1 reflect type: int32 settable=true int: 5 -reflect type: slice +reflect type: slice comparable=false slice: string 2 2 pointer: true nil: false @@ -141,15 +141,15 @@ reflect type: slice string: Z 1 reflect type: uint8 uint: 90 -reflect type: slice +reflect type: slice comparable=false slice: uint8 0 0 pointer: false nil: true -reflect type: slice +reflect type: slice comparable=false slice: uint8 0 0 pointer: true nil: false -reflect type: slice +reflect type: slice comparable=false slice: float32 2 2 pointer: true nil: false @@ -159,7 +159,7 @@ reflect type: slice indexing: 1 reflect type: float32 settable=true float: +1.320000e+000 -reflect type: slice +reflect type: slice comparable=false slice: float64 2 2 pointer: true nil: false @@ -169,7 +169,7 @@ reflect type: slice indexing: 1 reflect type: float64 settable=true float: +1.640000e+000 -reflect type: slice +reflect type: slice comparable=false slice: complex64 2 2 pointer: true nil: false @@ -179,7 +179,7 @@ reflect type: slice indexing: 1 reflect type: complex64 settable=true complex: (+1.640000e+000+3.000000e-001i) -reflect type: slice +reflect type: slice comparable=false slice: complex128 2 2 pointer: true nil: false @@ -189,7 +189,7 @@ reflect type: slice indexing: 1 reflect type: complex128 settable=true complex: (+1.128000e+000+4.000000e-001i) -reflect type: slice +reflect type: slice comparable=false slice: uint8 3 3 pointer: true nil: false @@ -216,16 +216,16 @@ reflect type: array uint: 3 reflect type: uint8 uint: 5 -reflect type: func +reflect type: func comparable=false func nil: true -reflect type: func +reflect type: func comparable=false func nil: false -reflect type: map +reflect type: map comparable=false map nil: true -reflect type: map +reflect type: map comparable=false map nil: false reflect type: struct @@ -255,7 +255,7 @@ reflect type: struct embedded: false reflect type: int8 int: 123 -reflect type: struct +reflect type: struct comparable=false struct: 5 field: 0 n tag: foo:"bar" @@ -285,7 +285,7 @@ reflect type: struct field: 3 buf tag: embedded: false - reflect type: slice + reflect type: slice comparable=false slice: uint8 2 2 pointer: true nil: false @@ -298,7 +298,7 @@ reflect type: struct field: 4 Buf tag: embedded: false - reflect type: slice + reflect type: slice comparable=false slice: uint8 1 1 pointer: true nil: false |