私は次のような関数を作成しようとしています
*struct
[]*struct
map[string]*struct
ここで、構造体は特定の構造体だけではなく、任意の構造体にすることができます。インターフェースをまたはに変換すると*struct
正常[]*struct
に動作します。ただし、マップではエラーが発生します。
リフレクト後、map[] であることが示されますが、範囲を反復処理しようとするとエラーが発生します。
コードはこちら
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)
}
interface{}
マップに変換して反復処理したり、その要素を取得したりする方法はありますか。
ベストアンサー1
ここで反映する必要はありません。次を試してください:
v, ok := in.(map[string]*Book)
if !ok {
// Can't assert, handle error.
}
for _, s := range v {
fmt.Printf("Value: %v\n", s)
}
関数の残りの部分も同様です。リフレクションを使用しているように見えますが、タイプスイッチ。
あるいは、ここでリフレクションを使いたい場合(あまり意味がありませんが)、次のようにすることもできます。Value.MapKeys
ValueOfの結果(答えを参照)https://stackoverflow.com/a/38186057/714501)