如何创建一个通用函数来解组所有类型?

huangapple go评论115阅读模式
英文:

How to create a generic function to unmarshal all types?

问题

我有一个下面的函数,我想要将它变成通用的:

  1. func genericUnmarshal(file string, v interface{}) error {
  2. raw, err := ioutil.ReadFile(file)
  3. if err != nil {
  4. return err
  5. }
  6. return json.Unmarshal(raw, v)
  7. }

现在你可以使用这个通用函数来解析 Type1 或 Type2,而不需要为每种类型创建一个函数。你只需要将相应的类型作为参数传递给 v,然后调用这个函数即可。例如:

  1. var type1 Type1
  2. err := genericUnmarshal("file.json", &type1)
  3. if err != nil {
  4. fmt.Println(err.Error())
  5. os.Exit(1)
  6. }
  7. var type2 Type2
  8. err = genericUnmarshal("file.json", &type2)
  9. if err != nil {
  10. fmt.Println(err.Error())
  11. os.Exit(1)
  12. }

这样你就可以重复使用同一个函数来解析不同的类型了。

英文:

I have a function below, and I would like to make it generic:

  1. func genericUnmarshalForType1(file string) Type1 {
  2. raw, err := ioutil.ReadFile(file)
  3. if err != nil {
  4. fmt.Println(err.Error())
  5. os.Exit(1)
  6. }
  7. var type1 Type1
  8. json.Unmarshal(raw, &type1)
  9. }

I would like to create a function that accepts Type1 or Type2 without the need to create a function per type. How can I do this?

答案1

得分: 5

按照json.Unmarshal的方式进行操作:

  1. func genericUnmarshal(file string, v interface{}) {
  2. // 模拟文件。
  3. raw := []byte(`{"a":42,"b":"foo"}`)
  4. err := json.Unmarshal(raw, v)
  5. if err != nil {
  6. // 处理错误
  7. fmt.Println("解析错误:", err)
  8. return
  9. }
  10. }

Playground: http://play.golang.org/p/iO-cbK50BE.

你可以通过返回遇到的任何错误来改进这个函数。

英文:

Do it the same way json.Unmarshal does it:

  1. func genericUnmarshal(file string, v interface{}) {
  2. // File emulation.
  3. raw := []byte(`{"a":42,"b":"foo"}`)
  4. json.Unmarshal(raw, v)
  5. }

Playground: http://play.golang.org/p/iO-cbK50BE.

You can make this function better by actually returning any errors encountered.

答案2

得分: 0

Go语言不支持泛型,但你可以编写类似以下的代码:

  1. func genericUnmarshalForType1(file string) interface{} {
  2. raw, err := ioutil.ReadFile(file)
  3. if err != nil {
  4. fmt.Println(err.Error())
  5. os.Exit(1)
  6. }
  7. var x interface{}
  8. if err = json.NewDecoder(raw).Decode(&x); err != nil {
  9. return nil
  10. }
  11. return x
  12. }
  13. func main() {
  14. x := genericUnmarshalForType1("filename.json");
  15. var t1 Type1
  16. var t2 Type2
  17. switch t := x.(type) {
  18. case Type1:
  19. t1 = t
  20. case Type2:
  21. t2 = t
  22. }
  23. }

另外,我建议你阅读一下关于使用Unmarshal和数据类型的文章:http://attilaolah.eu/2013/11/29/json-decoding-in-go/

英文:

Go doesn't support generics, but you can write something like this:

  1. func genericUnmarshalForType1(file string) interface{} {
  2. raw, err := ioutil.ReadFile(file)
  3. if err != nil {
  4. fmt.Println(err.Error())
  5. os.Exit(1)
  6. }
  7. var x interface{}
  8. if err = json.NewDecoder(raw).Decode(x); err != nil {
  9. return nil
  10. }
  11. return x
  12. }
  13. func main() {
  14. x := genericUnmarshalForType1("filename.json");
  15. var t1 Type1
  16. var t2 Type2
  17. switch t := x.(type) {
  18. case Type1:
  19. t1 = t
  20. case Type2:
  21. t2 = t
  22. }
  23. }

Also I recommend you to read http://attilaolah.eu/2013/11/29/json-decoding-in-go/ about Unmarshal using and data types.

huangapple
  • 本文由 发表于 2015年12月24日 01:13:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/34440646.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定