Skip to content

Commit 9a1cde4

Browse files
ydnardeadprogram
authored andcommitted
src/reflect: implement Value.Equal
Implementation copied from Go.
1 parent 20fc814 commit 9a1cde4

File tree

1 file changed

+75
-1
lines changed

1 file changed

+75
-1
lines changed

src/reflect/value.go

+75-1
Original file line numberDiff line numberDiff line change
@@ -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.
274286
func (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

278352
func (v Value) Addr() Value {

0 commit comments

Comments
 (0)