mirror of
https://github.com/golang/go
synced 2024-11-20 09:24:50 -07:00
reflect: add Type.Comparable
Like most of the Type methods, the definition of Comparable is what the Go spec says it is. Fixes #7911. LGTM=gri R=gri, r CC=golang-codereviews https://golang.org/cl/144020043
This commit is contained in:
parent
653fb6d872
commit
a325f4f2b3
@ -3185,6 +3185,44 @@ func TestConvert(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ComparableStruct struct {
|
||||||
|
X int
|
||||||
|
}
|
||||||
|
|
||||||
|
type NonComparableStruct struct {
|
||||||
|
X int
|
||||||
|
Y map[string]int
|
||||||
|
}
|
||||||
|
|
||||||
|
var comparableTests = []struct {
|
||||||
|
typ Type
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{TypeOf(1), true},
|
||||||
|
{TypeOf("hello"), true},
|
||||||
|
{TypeOf(new(byte)), true},
|
||||||
|
{TypeOf((func())(nil)), false},
|
||||||
|
{TypeOf([]byte{}), false},
|
||||||
|
{TypeOf(map[string]int{}), false},
|
||||||
|
{TypeOf(make(chan int)), true},
|
||||||
|
{TypeOf(1.5), true},
|
||||||
|
{TypeOf(false), true},
|
||||||
|
{TypeOf(1i), true},
|
||||||
|
{TypeOf(ComparableStruct{}), true},
|
||||||
|
{TypeOf(NonComparableStruct{}), false},
|
||||||
|
{TypeOf([10]map[string]int{}), false},
|
||||||
|
{TypeOf([10]string{}), true},
|
||||||
|
{TypeOf(new(interface{})).Elem(), true},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComparable(t *testing.T) {
|
||||||
|
for _, tt := range comparableTests {
|
||||||
|
if ok := tt.typ.Comparable(); ok != tt.ok {
|
||||||
|
t.Errorf("TypeOf(%v).Comparable() = %v, want %v", tt.typ, ok, tt.ok)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestOverflow(t *testing.T) {
|
func TestOverflow(t *testing.T) {
|
||||||
if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
|
if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
|
||||||
t.Errorf("%v wrongly overflows float64", 1e300)
|
t.Errorf("%v wrongly overflows float64", 1e300)
|
||||||
|
@ -96,6 +96,9 @@ type Type interface {
|
|||||||
// ConvertibleTo returns true if a value of the type is convertible to type u.
|
// ConvertibleTo returns true if a value of the type is convertible to type u.
|
||||||
ConvertibleTo(u Type) bool
|
ConvertibleTo(u Type) bool
|
||||||
|
|
||||||
|
// Comparable returns true if values of this type are comparable.
|
||||||
|
Comparable() bool
|
||||||
|
|
||||||
// Methods applicable only to some types, depending on Kind.
|
// Methods applicable only to some types, depending on Kind.
|
||||||
// The methods allowed for each kind are:
|
// The methods allowed for each kind are:
|
||||||
//
|
//
|
||||||
@ -248,7 +251,7 @@ type rtype struct {
|
|||||||
align uint8 // alignment of variable with this type
|
align uint8 // alignment of variable with this type
|
||||||
fieldAlign uint8 // alignment of struct field with this type
|
fieldAlign uint8 // alignment of struct field with this type
|
||||||
kind uint8 // enumeration for C
|
kind uint8 // enumeration for C
|
||||||
alg *uintptr // algorithm table (../runtime/runtime.h:/Alg)
|
alg *typeAlg // algorithm table (../runtime/runtime.h:/Alg)
|
||||||
gc [2]unsafe.Pointer // garbage collection data
|
gc [2]unsafe.Pointer // garbage collection data
|
||||||
string *string // string form; unnecessary but undeniably useful
|
string *string // string form; unnecessary but undeniably useful
|
||||||
*uncommonType // (relatively) uncommon fields
|
*uncommonType // (relatively) uncommon fields
|
||||||
@ -256,6 +259,15 @@ type rtype struct {
|
|||||||
zero unsafe.Pointer // pointer to zero value
|
zero unsafe.Pointer // pointer to zero value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type typeAlg struct {
|
||||||
|
// function for hashing objects of this type
|
||||||
|
// (ptr to object, size, seed) -> hash
|
||||||
|
hash func(unsafe.Pointer, uintptr, uintptr) uintptr
|
||||||
|
// function for comparing objects of this type
|
||||||
|
// (ptr to object A, ptr to object B, size) -> ==?
|
||||||
|
equal func(unsafe.Pointer, unsafe.Pointer, uintptr) bool
|
||||||
|
}
|
||||||
|
|
||||||
// Method on non-interface type
|
// Method on non-interface type
|
||||||
type method struct {
|
type method struct {
|
||||||
name *string // name of method
|
name *string // name of method
|
||||||
@ -1096,6 +1108,10 @@ func (t *rtype) ConvertibleTo(u Type) bool {
|
|||||||
return convertOp(uu, t) != nil
|
return convertOp(uu, t) != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *rtype) Comparable() bool {
|
||||||
|
return t.alg != nil && t.alg.equal != nil
|
||||||
|
}
|
||||||
|
|
||||||
// implements returns true if the type V implements the interface type T.
|
// implements returns true if the type V implements the interface type T.
|
||||||
func implements(T, V *rtype) bool {
|
func implements(T, V *rtype) bool {
|
||||||
if T.Kind() != Interface {
|
if T.Kind() != Interface {
|
||||||
|
Loading…
Reference in New Issue
Block a user