fix: handling values in map of interfaces
This commit is contained in:
18
_test/map24.go
Normal file
18
_test/map24.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
jb := []byte(`{"property": "test"}`)
|
||||
params := map[string]interface{}{"foo": 1}
|
||||
if err := json.Unmarshal(jb, ¶ms); err != nil {
|
||||
panic("marshal failed.")
|
||||
}
|
||||
fmt.Println(params["foo"], params["property"])
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 1 test
|
||||
26
_test/map25.go
Normal file
26
_test/map25.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
jb := []byte(`{"num": "2"}`)
|
||||
params := map[string]interface{}{"foo": "1"}
|
||||
if err := json.Unmarshal(jb, ¶ms); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sum := 0
|
||||
for _, v := range params {
|
||||
i, err := strconv.Atoi(v.(string))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sum += i
|
||||
}
|
||||
println(sum)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 3
|
||||
@@ -659,7 +659,7 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
|
||||
wireChild(n)
|
||||
t := n.child[0].typ
|
||||
switch t.cat {
|
||||
case ptrT:
|
||||
case aliasT, ptrT:
|
||||
n.typ = t.val
|
||||
if t.val.cat == valueT {
|
||||
n.typ = &itype{cat: valueT, rtype: t.val.rtype.Elem()}
|
||||
|
||||
@@ -1032,6 +1032,9 @@ func getIndexArray(n *node) {
|
||||
}
|
||||
}
|
||||
|
||||
// valueInterfaceType is the reflection type of valueInterface
|
||||
var valueInterfaceType = reflect.TypeOf((*valueInterface)(nil)).Elem()
|
||||
|
||||
// getIndexMap retrieves map value from index
|
||||
func getIndexMap(n *node) {
|
||||
dest := genValue(n)
|
||||
@@ -1057,7 +1060,11 @@ func getIndexMap(n *node) {
|
||||
z = reflect.New(n.child[0].typ.val.frameType()).Elem()
|
||||
n.exec = func(f *frame) bltn {
|
||||
if v := value0(f).MapIndex(mi); v.IsValid() {
|
||||
dest(f).Set(v.Elem())
|
||||
if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
|
||||
dest(f).Set(e)
|
||||
} else {
|
||||
dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
|
||||
}
|
||||
} else {
|
||||
dest(f).Set(z)
|
||||
}
|
||||
@@ -1091,7 +1098,11 @@ func getIndexMap(n *node) {
|
||||
z = reflect.New(n.child[0].typ.val.frameType()).Elem()
|
||||
n.exec = func(f *frame) bltn {
|
||||
if v := value0(f).MapIndex(value1(f)); v.IsValid() {
|
||||
dest(f).Set(v.Elem())
|
||||
if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
|
||||
dest(f).Set(e)
|
||||
} else {
|
||||
dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
|
||||
}
|
||||
} else {
|
||||
dest(f).Set(z)
|
||||
}
|
||||
@@ -1137,7 +1148,11 @@ func getIndexMap2(n *node) {
|
||||
n.exec = func(f *frame) bltn {
|
||||
v := value0(f).MapIndex(mi)
|
||||
if v.IsValid() {
|
||||
dest(f).Set(v.Elem())
|
||||
if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
|
||||
dest(f).Set(e)
|
||||
} else {
|
||||
dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
|
||||
}
|
||||
}
|
||||
if doStatus {
|
||||
value2(f).SetBool(v.IsValid())
|
||||
@@ -1169,7 +1184,11 @@ func getIndexMap2(n *node) {
|
||||
n.exec = func(f *frame) bltn {
|
||||
v := value0(f).MapIndex(value1(f))
|
||||
if v.IsValid() {
|
||||
dest(f).Set(v.Elem())
|
||||
if e := v.Elem(); e.Type().AssignableTo(valueInterfaceType) {
|
||||
dest(f).Set(e)
|
||||
} else {
|
||||
dest(f).Set(reflect.ValueOf(valueInterface{n, e}))
|
||||
}
|
||||
}
|
||||
if doStatus {
|
||||
value2(f).SetBool(v.IsValid())
|
||||
@@ -1900,7 +1919,11 @@ func rangeMap(n *node) {
|
||||
return fnext
|
||||
}
|
||||
f.data[index0].Set(iter.Key())
|
||||
f.data[index1].Set(iter.Value().Elem())
|
||||
if e := iter.Value().Elem(); e.Type().AssignableTo(valueInterfaceType) {
|
||||
f.data[index1].Set(e)
|
||||
} else {
|
||||
f.data[index1].Set(reflect.ValueOf(valueInterface{n, e}))
|
||||
}
|
||||
return tnext
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -79,7 +79,7 @@ func genValue(n *node) func(*frame) reflect.Value {
|
||||
case basicLit:
|
||||
v := n.rval
|
||||
if !v.IsValid() {
|
||||
v = reflect.New(reflect.TypeOf((*interface{})(nil)).Elem()).Elem()
|
||||
v = reflect.New(interf).Elem()
|
||||
}
|
||||
return func(f *frame) reflect.Value { return v }
|
||||
case funcDecl:
|
||||
@@ -149,10 +149,9 @@ func genValueRangeArray(n *node) func(*frame) reflect.Value {
|
||||
|
||||
func genValueInterfacePtr(n *node) func(*frame) reflect.Value {
|
||||
value := genValue(n)
|
||||
it := reflect.TypeOf((*interface{})(nil)).Elem()
|
||||
|
||||
return func(f *frame) reflect.Value {
|
||||
v := reflect.New(it).Elem()
|
||||
v := reflect.New(interf).Elem()
|
||||
v.Set(value(f))
|
||||
return v.Addr()
|
||||
}
|
||||
@@ -179,7 +178,7 @@ func genValueInterface(n *node) func(*frame) reflect.Value {
|
||||
|
||||
func zeroInterfaceValue() reflect.Value {
|
||||
n := &node{kind: basicLit, typ: &itype{cat: nilT, untyped: true}}
|
||||
v := reflect.New(reflect.TypeOf((*interface{})(nil)).Elem()).Elem()
|
||||
v := reflect.New(interf).Elem()
|
||||
return reflect.ValueOf(valueInterface{n, v})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user