@@ -3320,22 +3320,77 @@ func (v Value) Comparable() bool {
3320
3320
}
3321
3321
3322
3322
// Equal reports true if v is equal to u.
3323
- // For valid values, if one of them is non-comparable, and the other is comparable,
3324
- // Equal reports false; if v and u are both non-comparable, Equal will panic.
3323
+ // For two invalid values, Equal will report true.
3324
+ // For an interface value, Equal will compare the value within the interface.
3325
+ // Otherwise, If the values have different types, Equal will report false.
3326
+ // Otherwise, for arrays and structs Equal will compare each element in order,
3327
+ // and report false if it finds non-equal elements.
3328
+ // During all comparisons, if values of the same type are compared,
3329
+ // and the type is not comparable, Equal will panic.
3325
3330
func (v Value ) Equal (u Value ) bool {
3331
+ if v .Kind () == Interface {
3332
+ v = v .Elem ()
3333
+ }
3334
+ if u .Kind () == Interface {
3335
+ u = u .Elem ()
3336
+ }
3337
+
3326
3338
if ! v .IsValid () || ! u .IsValid () {
3327
3339
return v .IsValid () == u .IsValid ()
3328
3340
}
3329
3341
3330
- if v .Comparable () || u . Comparable () {
3331
- return valueInterface ( v , false ) == valueInterface ( u , false )
3342
+ if v .Kind () != u . Kind () || v . Type () != u . Type () {
3343
+ return false
3332
3344
}
3333
3345
3334
- if u .Kind () == Interface && v .kind () == Interface { // this case is for nil interface value
3335
- return v .Elem ().Equal (u .Elem ())
3346
+ // Handle ach Kind directly rather than calling valueInterface
3347
+ // to avoid allocating.
3348
+ switch v .Kind () {
3349
+ default :
3350
+ panic ("reflect.Value.Equal: invalid Kind" )
3351
+ case Bool :
3352
+ return v .Bool () == u .Bool ()
3353
+ case Int , Int8 , Int16 , Int32 , Int64 :
3354
+ return v .Int () == u .Int ()
3355
+ case Uint , Uint8 , Uint16 , Uint32 , Uint64 , Uintptr :
3356
+ return v .Uint () == u .Uint ()
3357
+ case Float32 , Float64 :
3358
+ return v .Float () == u .Float ()
3359
+ case Complex64 , Complex128 :
3360
+ return v .Complex () == u .Complex ()
3361
+ case String :
3362
+ return v .String () == u .String ()
3363
+ case Chan , Pointer , UnsafePointer :
3364
+ return v .Pointer () == u .Pointer ()
3365
+ case Array :
3366
+ // u and v have the same type so they have the same length
3367
+ vl := v .Len ()
3368
+ if vl == 0 {
3369
+ // panic on [0]func()
3370
+ if ! v .Type ().Elem ().Comparable () {
3371
+ break
3372
+ }
3373
+ return true
3374
+ }
3375
+ for i := 0 ; i < vl ; i ++ {
3376
+ if ! v .Index (i ).Equal (u .Index (i )) {
3377
+ return false
3378
+ }
3379
+ }
3380
+ return true
3381
+ case Struct :
3382
+ // u and v have the same type so they have the same fields
3383
+ nf := v .NumField ()
3384
+ for i := 0 ; i < nf ; i ++ {
3385
+ if ! v .Field (i ).Equal (u .Field (i )) {
3386
+ return false
3387
+ }
3388
+ }
3389
+ return true
3390
+ case Func , Map , Slice :
3391
+ break
3336
3392
}
3337
-
3338
- panic ("reflect.Value.Equal using two non-comparable values" )
3393
+ panic ("reflect.Value.Equal: values of type " + v .Type ().String () + " are not comparable" )
3339
3394
}
3340
3395
3341
3396
// convertOp returns the function to convert a value of type src
0 commit comments