mirror of
https://github.com/golang/go
synced 2024-11-20 07:04:40 -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) {
|
||||
if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
|
||||
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(u Type) bool
|
||||
|
||||
// Comparable returns true if values of this type are comparable.
|
||||
Comparable() bool
|
||||
|
||||
// Methods applicable only to some types, depending on Kind.
|
||||
// The methods allowed for each kind are:
|
||||
//
|
||||
@ -248,7 +251,7 @@ type rtype struct {
|
||||
align uint8 // alignment of variable with this type
|
||||
fieldAlign uint8 // alignment of struct field with this type
|
||||
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
|
||||
string *string // string form; unnecessary but undeniably useful
|
||||
*uncommonType // (relatively) uncommon fields
|
||||
@ -256,6 +259,15 @@ type rtype struct {
|
||||
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
|
||||
type method struct {
|
||||
name *string // name of method
|
||||
@ -1096,6 +1108,10 @@ func (t *rtype) ConvertibleTo(u Type) bool {
|
||||
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.
|
||||
func implements(T, V *rtype) bool {
|
||||
if T.Kind() != Interface {
|
||||
|
Loading…
Reference in New Issue
Block a user