From a5ddc688450368205658b61a99b6e23757b47967 Mon Sep 17 00:00:00 2001 From: Damian Gryski Date: Thu, 16 Mar 2023 21:23:17 -0700 Subject: [PATCH] reflect: unpack interfaces in MapKeys() if needed --- src/reflect/value.go | 11 ++++++++++- src/reflect/value_test.go | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/reflect/value.go b/src/reflect/value.go index c58d7084..0b7a5701 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -779,8 +779,17 @@ func (v Value) MapKeys() []Value { k := New(v.typecode.Key()) e := New(v.typecode.Elem()) + keyType := v.typecode.Key().(*rawType) + isKeyStoredAsInterface := keyType.Kind() != String && !keyType.isBinary() + for hashmapNext(v.pointer(), it, k.value, e.value) { - keys = append(keys, k.Elem()) + if isKeyStoredAsInterface { + intf := *(*interface{})(k.value) + v := ValueOf(intf) + keys = append(keys, v) + } else { + keys = append(keys, k.Elem()) + } k = New(v.typecode.Key()) } diff --git a/src/reflect/value_test.go b/src/reflect/value_test.go index 7881e27b..81533713 100644 --- a/src/reflect/value_test.go +++ b/src/reflect/value_test.go @@ -134,6 +134,20 @@ func TestTinyMap(t *testing.T) { t.Errorf("m[hello, 4]=%v, want 6", six) } + keys := refsimap.MapKeys() + if len(keys) != 1 { + t.Errorf("refsimap: MapKeys()=%v, want 1", len(keys)) + } + if keys[0].Type() != TypeOf(stringint{}) { + t.Errorf("keys[0] has wrong type: %v", keys[0].Type().String()) + } + + sikey := keys[0].Interface().(stringint) + + if sikey != (stringint{"hello", 4}) { + t.Errorf("sikey has unexpected value: %#v", sikey) + } + // make sure we can look up interface keys with reflection type unmarshalerText struct { A, B string