@@ -271,8 +271,82 @@ func (v Value) Comparable() bool {
271271 }
272272}
273273
274+ // Equal reports true if v is equal to u.
275+ // For two invalid values, Equal will report true.
276+ // For an interface value, Equal will compare the value within the interface.
277+ // Otherwise, If the values have different types, Equal will report false.
278+ // Otherwise, for arrays and structs Equal will compare each element in order,
279+ // and report false if it finds non-equal elements.
280+ // During all comparisons, if values of the same type are compared,
281+ // and the type is not comparable, Equal will panic.
282+ //
283+ // Copyright 2009 The Go Authors. All rights reserved.
284+ // Use of this source code is governed by a BSD-style
285+ // license that can be found in the LICENSE file.
274286func (v Value ) Equal (u Value ) bool {
275- panic ("unimplemented: reflect.Value.Equal" )
287+ if v .Kind () == Interface {
288+ v = v .Elem ()
289+ }
290+ if u .Kind () == Interface {
291+ u = u .Elem ()
292+ }
293+
294+ if ! v .IsValid () || ! u .IsValid () {
295+ return v .IsValid () == u .IsValid ()
296+ }
297+
298+ if v .Kind () != u .Kind () || v .Type () != u .Type () {
299+ return false
300+ }
301+
302+ // Handle each Kind directly rather than calling valueInterface
303+ // to avoid allocating.
304+ switch v .Kind () {
305+ default :
306+ panic ("reflect.Value.Equal: invalid Kind" )
307+ case Bool :
308+ return v .Bool () == u .Bool ()
309+ case Int , Int8 , Int16 , Int32 , Int64 :
310+ return v .Int () == u .Int ()
311+ case Uint , Uint8 , Uint16 , Uint32 , Uint64 , Uintptr :
312+ return v .Uint () == u .Uint ()
313+ case Float32 , Float64 :
314+ return v .Float () == u .Float ()
315+ case Complex64 , Complex128 :
316+ return v .Complex () == u .Complex ()
317+ case String :
318+ return v .String () == u .String ()
319+ case Chan , Pointer , UnsafePointer :
320+ return v .Pointer () == u .Pointer ()
321+ case Array :
322+ // u and v have the same type so they have the same length
323+ vl := v .Len ()
324+ if vl == 0 {
325+ // panic on [0]func()
326+ if ! v .Type ().Elem ().Comparable () {
327+ break
328+ }
329+ return true
330+ }
331+ for i := 0 ; i < vl ; i ++ {
332+ if ! v .Index (i ).Equal (u .Index (i )) {
333+ return false
334+ }
335+ }
336+ return true
337+ case Struct :
338+ // u and v have the same type so they have the same fields
339+ nf := v .NumField ()
340+ for i := 0 ; i < nf ; i ++ {
341+ if ! v .Field (i ).Equal (u .Field (i )) {
342+ return false
343+ }
344+ }
345+ return true
346+ case Func , Map , Slice :
347+ break
348+ }
349+ panic ("reflect.Value.Equal: values of type " + v .Type ().String () + " are not comparable" )
276350}
277351
278352func (v Value ) Addr () Value {
0 commit comments