【发布时间】:2020-09-12 02:37:39
【问题描述】:
我正在尝试通过字符串输入选择一个结构,然后根据返回的 JSON 对象或数组,解组 JSON。想办法将结构反映到切片结构上是否正确?如果是这样,如何通过反射来做到这一点? 问候, 彼得
package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
)
type NameStruct struct {
Name string
}
func main() {
jsonData := []byte(`[{"name":"james"},{"name":"steven"}]`)
returnModel := InitializeModel("NameStruct", jsonData)
fmt.Println(returnModel)
jsonData = []byte(`{"name":"james"}`)
returnModel = InitializeModel("NameStruct", jsonData)
fmt.Println(returnModel)
}
func getModelByName(modelType string) interface{} {
modelMap := make(map[string]interface{})
modelMap["NameStruct"] = new(NameStruct)
//don't want to do this
modelMap["arrNameStruct"] = new([]NameStruct)
return modelMap[modelType]
}
func InitializeModel(modelName string, jsonData []byte) interface{} {
switch IsArray(jsonData) {
case true:
// some conversion here, how?
returnModel := getModelByName("NameStruct")
if err := json.Unmarshal(jsonData, &returnModel); err != nil {
log.Println(err)
}
return returnModel
case false:
returnModel := getModelByName("NameStruct")
if err := json.Unmarshal(jsonData, &returnModel); err != nil {
log.Println(err)
}
return returnModel
}
return nil
}
func IsArray(jsonData []byte) bool {
return (bytes.HasPrefix(jsonData, []byte("["))) && (bytes.HasSuffix(jsonData, []byte("]")))
}
【问题讨论】:
-
这似乎不是一个好主意,您是否正在尝试解决某个特定问题?例如,在您的代码中,与使用该语言提供的初始化原语相比,具体的优势是什么?例如play.golang.com/p/JlSdzo7uyN_L
-
我有大约 50 个结构。这将在“getModelByName”函数中给我 100 行代码。我认为有更好的方法....我正在尝试解决有时我得到一个对象 json 的问题,有时我得到一个指向同一个结构的数组 json 来解组。
-
如果你真的需要对返回的
returnModel做一些有意义的事情,你必须对值进行类型断言,在我看来,这完全违背了getModelByName的目的。我可以看到getModelByName方法只有在您不太关心底层类型并且只需要将数据传递到某个地方(以另一种格式)的情况下才有意义,例如,例如,将 json 转换为 xml。 -
我想要完成的是,我需要解组大约 50 个 api 端点。例如1 个端点可以返回一个带有字段的 json 对象,并且同一端点有时可以返回一个具有相同对象字段的数组。因此,如果它是一个对象,我可以将它解组到 NameStruct 中,如果它是一个数组到 []NameStruct 但我不想声明 2 个结构,因为它们拥有相同的字段。
-
@mkopriva 啊 - 认为可以在包级别执行此操作 - 看起来只有从特定结构值或其本机字段开始时才有可能。我想
Register函数将是实现这一目标的最简单的方法。
标签: go struct interface reflect