reflect: convert map elements to an interface, if needed

Этот коммит содержится в:
Damian Gryski 2023-03-11 15:49:19 -08:00 коммит произвёл Ron Evans
родитель adaa7ca27a
коммит c0f8f129c0
2 изменённых файлов: 27 добавлений и 0 удалений

Просмотреть файл

@ -1370,6 +1370,15 @@ func (v Value) SetMapIndex(key, elem Value) {
panic("reflect.Value.SetMapIndex: incompatible types for value") panic("reflect.Value.SetMapIndex: incompatible types for value")
} }
// make elem an interface if it needs to be converted
if v.typecode.elem().Kind() == Interface && elem.typecode.Kind() != Interface {
intf := composeInterface(unsafe.Pointer(elem.typecode), elem.value)
elem = Value{
typecode: v.typecode.elem(),
value: unsafe.Pointer(&intf),
}
}
if key.Kind() == String { if key.Kind() == String {
if del { if del {
hashmapStringDelete(v.pointer(), *(*string)(key.value)) hashmapStringDelete(v.pointer(), *(*string)(key.value))

Просмотреть файл

@ -192,6 +192,24 @@ func TestTinyMap(t *testing.T) {
} }
} }
func TestMapInterfaceElem(t *testing.T) {
m := make(map[string]interface{})
refm := ValueOf(m)
four := ValueOf(4)
hello := ValueOf("hello")
refm.SetMapIndex(hello, four)
if v := refm.MapIndex(hello).Interface().(int); v != 4 {
t.Errorf("failed to get value assigned to interface via MapIndex")
}
if v := m["hello"].(int); v != 4 {
t.Errorf("failed to get value assigned to interface via direct lookup")
}
}
func TestTinySlice(t *testing.T) { func TestTinySlice(t *testing.T) {
s := []int{0, 10, 20} s := []int{0, 10, 20}
refs := ValueOf(s) refs := ValueOf(s)