我正在尝试对另一个软件进行扩展,该软件向 Go 中的应用程序发送请求。在 Go 程序(我现在将其称为“程序”)中,一个目的是将 JSON 文件转换为可以迭代的格式。这是我正在使用的示例 JSON 格式:
{
"name": "Game-Name",
"tree": {
"$className": "DataModel",
"ReplicatedStorage": {
"$path": "src/ReplicatedStorage"
},
"ServerScriptService": {
"$path": "src/ServerScriptService"
},
"ReplicatedFirst": {
"$path": "src/ReplicatedFirst"
},
"ServerStorage": {
"$path": "src/ServerStorage"
}
}
}
想法是:
src
文件夹下创建一个文件夹,其中包含父地图的索引。例如,ReplicatedStorage
是路径为 src/ReplicatedStorage
下面是一个旨在执行此操作的过程函数:
func process(in interface{}) {
v := reflect.ValueOf(in)
if v.Kind() == reflect.Map {
for _, key := range v.MapKeys() {
strct := v.MapIndex(key)
index := key.Interface()
value := reflect.ValueOf(strct.Interface())
if index == "tree" {
for _, treeKey := range value.MapKeys() {
treeIndex := treeKey.Interface()
fmt.Println("KEY")
fmt.Println(treeIndex)
if treeIndex != "$className" {
fmt.Println("bug")
fmt.Println(treeKey)
a := key.MapIndex(value) // panic serving ...: reflect: call of reflect.Value.MapIndex on string Value
b := reflect.ValueOf(a.Interface())
for _, key2 := range b.MapKeys() {
index2 := key2.Interface()
value2 := reflect.ValueOf(key2.Interface())
fmt.Println(index2)
fmt.Println(value2)
}
}
}
}
}
}
}
注释是错误的地方和内容。我还想理想地做的一件事是不必堆叠 for 循环,因为那是非常臭的代码。
我是 Go 的新手,所以我确定解决方案很简单哈哈,感谢帮助和反馈。
谢谢!
使用 type assertions 而不是 reflect 包。使用 map indexing 查找值,而不是循环遍历键并查找匹配项。
func process(in interface{}) error {
top, ok := in.(map[string]interface{})
if !ok {
return errors.New("expected object at top level")
}
tree, ok := top["tree"].(map[string]interface{})
if !ok {
return errors.New(".tree not found")
}
name, ok := top["name"]
if !ok {
return errors.New(".name not found")
}
className, ok := tree["$className"].(string)
if !ok {
return errors.New(".tree.$className not found")
}
for k, v := range tree {
thing, ok := v.(map[string]interface{})
if !ok {
continue
}
path, ok := thing["$path"].(string)
if !ok {
continue
}
fmt.Println(name, className, k, path)
}
return nil
}