英文:
Instantiating a struct via name using a string in go
问题
我正在尝试创建一个函数,该函数接受一个[]byte
和一个interface{}
(表示struct
),并返回一个作为传递给该函数的struct
类型的interface{}
。
类似这样的代码:
package main
import (
"encoding/json"
"fmt"
)
func UnmarshalFromJSONArray(sms []byte, tt string) interface{} {
var ts interface{}
err := json.Unmarshal(sms, &ts)
if err != nil {
fmt.Println(err)
}
return ts
}
然后可以这样调用该方法:
type MyStructType struct {
Id int
Name string
Desc string
}
mst := "main.MyStructType"
ba := []byte(`{"Id":"3","Name":"Jack","Desc":"the man"}`)
stct := UnmarshalFromJSONArray(ba, mst)
out := stct.(MyStructType)
关键是在解组之前不需要知道MyStructType
的字段。我们只需要知道struct
的名称,并找到一种实例化它并用与其字段匹配的JSON字节数组数据填充的方法。希望这样做是可能的(在Java中使用反射是微不足道的)。因此,我想通过名称解组一个匿名的struct
类型,而不需要知道它有哪些字段。
有什么建议吗?
英文:
I am trying to create a function that takes a []byte
and an interface{}
(standing for the struct
) and returns an interface{}
as the struct
type passed into the func
.
Something like this:
package main
import (
"encoding/json"
)
func UnmarshalFromJSONArray(sms []byte,tt string) (interface{}) {
var ts = new(tt)
err := json.Unmarshal(sms,&ts)
if(err != nil) {
fmt.Println(err)
}
return sms
}
So that method would run something like this:
// let's say a struct has the following definition:
type MyStructType struct {
Id int
Name string
Desc string
}
// we can some how get its fully qualified class name (this may require reflection?) or pass it into the UnMarshal method direction some how.
mst := "package.MyStructType",
// and then assume a byte array ba that has JSON format for
ba := []byte(`{"Id":"3","Name":"Jack","Desc":"the man"}`)
stct := UnmarshalFromJSONArray(ba,mst)
MyStructureType out := stct
// leaving "stct" being the unmarshalled byte array which can be used like any other struct of type "MyStructureType"
The key being that I never need to know what the fields of MyStructureType
are before unmarshalling. All I need are the name of the struct
and some way to instance one and then populate it with JSON byte array data that matches its fields. Hopefully that is possible (it is trivial in java using reflection). So I want to basically unmarshal an anonymous struct
type by it's name without needing to know what fields it has.
Any suggestions?
答案1
得分: 4
简短的回答是这是不可能的。Go语言中没有字符串到类型的转换器。你可以创建一个字符串到reflect.Type的映射,但你需要提前知道可能的选项,或者需要提供调用者一种注册类型的方式(可能在init函数中)。
假设你已经找到了将字符串解析为其reflect.Type的方法,你可以简单地调用reflect.New(typ).Interface()来获取需要传递给json.Unmarshal()的指针。
最好的答案是尽量避免尝试这样做。在Go语言中写出符合惯用方式的Java代码实际上是不可能的。如果我对你的问题了解更多,我可以给你一个更符合惯用方式的Go语言解决方案。
英文:
The short answer is that this is impossible. There is no string to type translator in Go. You can make a map of strings to reflect.Type's, but you would need to know the possible options ahead of time or you need to provide the caller with a way to register types (perhaps in init).
Assuming you have found a way to resolve the string to its reflect.Type, you can simply call reflect.New(typ).Interface() to get the pointer you need to pass to json.Unmarshal().
The best answer is to avoid trying this all together. Writing idiomatic Java in Go isn't really possible. If I knew more about your problem, I could give you a more idiomatic Go solution.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论