我正在尝试创建一个可以接受以下
的函数 var elems= document.querySelectorAll('[name=feature[]')
for (var i=0;i<elems.length;i++)
{
var isChecked =elems[i].checked;
console.log(isChecked);
}
这里struct可以是任何结构,而不仅仅是特定结构。
将界面转换为*struct
[]*struct
map[string]*struct
或*struct
工作正常。
但是为地图提供错误。
反映后显示它是map [],但在尝试迭代范围时给出错误。
这是代码
[]*struct
有没有办法将package main
import (
"fmt"
"reflect"
)
type Book struct {
ID int
Title string
Year int
}
func process(in interface{}, isSlice bool, isMap bool) {
v := reflect.ValueOf(in)
if isSlice {
for i := 0; i < v.Len(); i++ {
strct := v.Index(i).Interface()
//... proccess struct
}
return
}
if isMap {
fmt.Printf("Type: %v\n", v) // map[]
for _, s := range v { // Error: cannot range over v (type reflect.Value)
fmt.Printf("Value: %v\n", s.Interface())
}
}
}
func main() {
b := Book{}
b.Title = "Learn Go Language"
b.Year = 2014
m := make(map[string]*Book)
m["1"] = &b
process(m, false, true)
}
转换成地图并迭代或获取它的元素。
答案 0 :(得分:22)
如果地图值可以是任何类型,则使用reflect来迭代地图:
if v.Kind() == reflect.Map {
for _, key := range v.MapKeys() {
strct := v.MapIndex(key)
fmt.Println(key.Interface(), strct.Interface())
}
}
如果有一组很小且已知的结构类型,那么可以使用type switch:
func process(in interface{}) {
switch v := in.(type) {
case map[string]*Book:
for s, b := range v {
// b has type *Book
fmt.Printf("%s: book=%v\n" s, b)
}
case map[string]*Author:
for s, a := range v {
// a has type *Author
fmt.Printf("%s: author=%v\n" s, a)
}
case []*Book:
for i, b := range v {
fmt.Printf("%d: book=%v\n" i, b)
}
case []*Author:
for i, a := range v {
fmt.Printf("%d: author=%v\n" i, a)
}
case *Book:
fmt.Ptintf("book=%v\n", v)
case *Author:
fmt.Printf("author=%v\n", v)
default:
// handle unknown type
}
}
答案 1 :(得分:19)
你不需要在这里反思。尝试:
v, ok := in.(map[string]*Book)
if !ok {
// Can't assert, handle error.
}
for _, s := range v {
fmt.Printf("Value: %v\n", s)
}
其余的功能也是如此。当type switch为您提供更好的服务时,您似乎正在使用反射。
或者,如果你坚持在这里使用反射(这没有多大意义),你也可以使用Value.MapKeys
和ValueOf的结果(参见答案https://stackoverflow.com/a/38186057/714501)
答案 2 :(得分:0)
使用包反射将 interface{}
转换为 map
的另一种方法是使用 MapRange
。
我引用:
<块引用>MapRange 返回地图的范围迭代器。如果 v 的 Kind 是,它会恐慌 不是地图。
调用 Next 来推进迭代器,调用 Key/Value 来访问每个条目。 当迭代器耗尽时,Next 返回 false。地图范围如下 与范围语句相同的迭代语义。
示例:
iter := reflect.ValueOf(m).MapRange()
for iter.Next() {
key := iter.Key().Interface()
value := iter.Value().Interface()
...
}
答案 3 :(得分:0)
这可能会有所帮助:
b := []byte(`{"keyw":"value"}`)
var f interface{}
json.Unmarshal(b, &f)
myMap := f.(map[string]interface{})
fmt.Println(myMap)