[解決済み] interface{}をmapに変換する方法
2022-02-19 18:17:28
質問
次のような関数を作成しようとしています。
*struct
[]*struct
map[string]*struct
ここで、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{}
をマップに変換して、その要素を反復したり取得したりします。
解決方法は?
マップの値が任意の型である場合、reflectを使用してマップを反復処理します。
if v.Kind() == reflect.Map {
for _, key := range v.MapKeys() {
strct := v.MapIndex(key)
fmt.Println(key.Interface(), strct.Interface())
}
}
構造体の種類が少なくて既知のものであれば タイプスイッチ を使用することができます。
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
}
}
関連
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] 辞書を値で並べ替えるにはどうしたらいいですか?
-
[解決済み] Pythonで辞書に新しいキーを追加するにはどうすればよいですか?
-
[解決済み] Pythonの辞書からキーを削除するにはどうしたらいいですか?
-
[解決済み] インターフェースと抽象クラスの違いは何ですか?
-
[解決済み] 2つのリストを辞書に変換するにはどうしたらいいですか?
-
[解決済み] インターフェースと抽象クラス(一般的なOO)
-
[解決済み] Goでマップにキーが含まれているかどうかを確認するには?
-
[解決済み】地図上のキーを削除する
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン