reflect: implement t.Comparable()
This is necessary to support the context package, which is a dependency of a lot of packages.
Этот коммит содержится в:
родитель
c19c738f52
коммит
e356bad4d1
3 изменённых файлов: 59 добавлений и 18 удалений
|
@ -398,6 +398,44 @@ func (t Type) AssignableTo(u Type) bool {
|
||||||
return false
|
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.
|
// A StructField describes a single field in a struct.
|
||||||
type StructField struct {
|
type StructField struct {
|
||||||
// Name indicates the field name.
|
// Name indicates the field name.
|
||||||
|
|
3
testdata/reflect.go
предоставленный
3
testdata/reflect.go
предоставленный
|
@ -268,6 +268,9 @@ func showValue(rv reflect.Value, indent string) {
|
||||||
if rv.CanSet() {
|
if rv.CanSet() {
|
||||||
print(" settable=", rv.CanSet())
|
print(" settable=", rv.CanSet())
|
||||||
}
|
}
|
||||||
|
if !rt.Comparable() {
|
||||||
|
print(" comparable=false")
|
||||||
|
}
|
||||||
println()
|
println()
|
||||||
switch rt.Kind() {
|
switch rt.Kind() {
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
|
|
36
testdata/reflect.txt
предоставленный
36
testdata/reflect.txt
предоставленный
|
@ -90,7 +90,7 @@ reflect type: ptr
|
||||||
nil: false
|
nil: false
|
||||||
reflect type: int settable=true
|
reflect type: int settable=true
|
||||||
int: 0
|
int: 0
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: uint8 3 3
|
slice: uint8 3 3
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -103,7 +103,7 @@ reflect type: slice
|
||||||
indexing: 2
|
indexing: 2
|
||||||
reflect type: uint8 settable=true
|
reflect type: uint8 settable=true
|
||||||
uint: 3
|
uint: 3
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: uint8 2 5
|
slice: uint8 2 5
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -113,7 +113,7 @@ reflect type: slice
|
||||||
indexing: 1
|
indexing: 1
|
||||||
reflect type: uint8 settable=true
|
reflect type: uint8 settable=true
|
||||||
uint: 0
|
uint: 0
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: int32 2 2
|
slice: int32 2 2
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -123,7 +123,7 @@ reflect type: slice
|
||||||
indexing: 1
|
indexing: 1
|
||||||
reflect type: int32 settable=true
|
reflect type: int32 settable=true
|
||||||
int: 5
|
int: 5
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: string 2 2
|
slice: string 2 2
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -141,15 +141,15 @@ reflect type: slice
|
||||||
string: Z 1
|
string: Z 1
|
||||||
reflect type: uint8
|
reflect type: uint8
|
||||||
uint: 90
|
uint: 90
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: uint8 0 0
|
slice: uint8 0 0
|
||||||
pointer: false
|
pointer: false
|
||||||
nil: true
|
nil: true
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: uint8 0 0
|
slice: uint8 0 0
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: float32 2 2
|
slice: float32 2 2
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -159,7 +159,7 @@ reflect type: slice
|
||||||
indexing: 1
|
indexing: 1
|
||||||
reflect type: float32 settable=true
|
reflect type: float32 settable=true
|
||||||
float: +1.320000e+000
|
float: +1.320000e+000
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: float64 2 2
|
slice: float64 2 2
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -169,7 +169,7 @@ reflect type: slice
|
||||||
indexing: 1
|
indexing: 1
|
||||||
reflect type: float64 settable=true
|
reflect type: float64 settable=true
|
||||||
float: +1.640000e+000
|
float: +1.640000e+000
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: complex64 2 2
|
slice: complex64 2 2
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -179,7 +179,7 @@ reflect type: slice
|
||||||
indexing: 1
|
indexing: 1
|
||||||
reflect type: complex64 settable=true
|
reflect type: complex64 settable=true
|
||||||
complex: (+1.640000e+000+3.000000e-001i)
|
complex: (+1.640000e+000+3.000000e-001i)
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: complex128 2 2
|
slice: complex128 2 2
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -189,7 +189,7 @@ reflect type: slice
|
||||||
indexing: 1
|
indexing: 1
|
||||||
reflect type: complex128 settable=true
|
reflect type: complex128 settable=true
|
||||||
complex: (+1.128000e+000+4.000000e-001i)
|
complex: (+1.128000e+000+4.000000e-001i)
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: uint8 3 3
|
slice: uint8 3 3
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -216,16 +216,16 @@ reflect type: array
|
||||||
uint: 3
|
uint: 3
|
||||||
reflect type: uint8
|
reflect type: uint8
|
||||||
uint: 5
|
uint: 5
|
||||||
reflect type: func
|
reflect type: func comparable=false
|
||||||
func
|
func
|
||||||
nil: true
|
nil: true
|
||||||
reflect type: func
|
reflect type: func comparable=false
|
||||||
func
|
func
|
||||||
nil: false
|
nil: false
|
||||||
reflect type: map
|
reflect type: map comparable=false
|
||||||
map
|
map
|
||||||
nil: true
|
nil: true
|
||||||
reflect type: map
|
reflect type: map comparable=false
|
||||||
map
|
map
|
||||||
nil: false
|
nil: false
|
||||||
reflect type: struct
|
reflect type: struct
|
||||||
|
@ -255,7 +255,7 @@ reflect type: struct
|
||||||
embedded: false
|
embedded: false
|
||||||
reflect type: int8
|
reflect type: int8
|
||||||
int: 123
|
int: 123
|
||||||
reflect type: struct
|
reflect type: struct comparable=false
|
||||||
struct: 5
|
struct: 5
|
||||||
field: 0 n
|
field: 0 n
|
||||||
tag: foo:"bar"
|
tag: foo:"bar"
|
||||||
|
@ -285,7 +285,7 @@ reflect type: struct
|
||||||
field: 3 buf
|
field: 3 buf
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: uint8 2 2
|
slice: uint8 2 2
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
@ -298,7 +298,7 @@ reflect type: struct
|
||||||
field: 4 Buf
|
field: 4 Buf
|
||||||
tag:
|
tag:
|
||||||
embedded: false
|
embedded: false
|
||||||
reflect type: slice
|
reflect type: slice comparable=false
|
||||||
slice: uint8 1 1
|
slice: uint8 1 1
|
||||||
pointer: true
|
pointer: true
|
||||||
nil: false
|
nil: false
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче