4.4.4-13 类型的比较规则
func isOrdered(typ Type) bool { return is(typ, IsOrdered) }
func Comparable(T Type) bool { return comparable(T, nil) } //
func comparable(T Type, seen map[Type]bool) bool {
if seen[T] {
return true
}
if seen == nil {
seen = make(map[Type]bool)
}
seen[T] = true
// If T is a type parameter not constrained by any type
// list (i.e., it's underlying type is the top type),
// T is comparable if it has the == method. Otherwise,
// the underlying type "wins". For instance
//
// interface{ comparable; type []byte }
//
// is not comparable because []byte is not comparable.
if t := asTypeParam(T); t != nil && optype(t) == theTop {
return t.Bound().IsComparable()
}
switch t := optype(T).(type) {
case *Basic:
// assume invalid types to be comparable
// to avoid follow-up errors
return t.kind != UntypedNil
case *Pointer, *Interface, *Chan:
return true
case *Struct:
for _, f := range t.fields {
if !comparable(f.typ, seen) {
return false
}
}
return true
case *Array:
return comparable(t.elem, seen)
case *Sum:
pred := func(t Type) bool {
return comparable(t, seen)
}
return t.is(pred)
case *TypeParam:
return t.Bound().IsComparable()
}
return false
}最后更新于