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

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

How to create a generic function to unmarshal all types?

问题

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

func genericUnmarshal(file string, v interface{}) error {
    raw, err := ioutil.ReadFile(file)
    if err != nil {
        return err
    }

    return json.Unmarshal(raw, v)
}

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

var type1 Type1
err := genericUnmarshal("file.json", &type1)
if err != nil {
    fmt.Println(err.Error())
    os.Exit(1)
}

var type2 Type2
err = genericUnmarshal("file.json", &type2)
if err != nil {
    fmt.Println(err.Error())
    os.Exit(1)
}

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

英文:

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

func genericUnmarshalForType1(file string) Type1 {

  raw, err := ioutil.ReadFile(file)

  if err != nil {
	  fmt.Println(err.Error())
	  os.Exit(1)
  }

  var type1 Type1

  json.Unmarshal(raw, &type1)
}

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的方式进行操作:

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

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

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

英文:

Do it the same way json.Unmarshal does it:

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

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

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

答案2

得分: 0

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

func genericUnmarshalForType1(file string) interface{} {

    raw, err := ioutil.ReadFile(file)

    if err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
    }

    var x interface{}
    if err = json.NewDecoder(raw).Decode(&x); err != nil {
        return nil
    }

    return x
}

func main() {
    x := genericUnmarshalForType1("filename.json");

    var t1 Type1
    var t2 Type2

    switch t := x.(type) {
    case Type1:
        t1 = t
    case Type2:
        t2 = t
    }
}

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

英文:

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

func genericUnmarshalForType1(file string) interface{} {

  	raw, err := ioutil.ReadFile(file)

  	if err != nil {
      	fmt.Println(err.Error())
      	os.Exit(1)
  	}

  	var x interface{}
  	if err = json.NewDecoder(raw).Decode(x); err != nil {
        return nil
    }

    return x
}

func main() {
	x := genericUnmarshalForType1("filename.json");

	var t1 Type1
	var t2 Type2

	switch t := x.(type) {
	case Type1:
	    t1 = t
	case Type2:
	    t2 = t
	}
}

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:

确定