How to use two JSON unmarshallers in the same project?

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

How to use two JSON unmarshallers in the same project?

问题

在进行JSON解组的POC时,我需要根据一些条件在我的Go代码中使用两个自定义的JSON提供程序。

  1. easyJson.unmarshal()
  2. json.unmarshal()

我面临的问题是,由于我们导入了自定义的easyJson代码,json.Unmarshal()也将使用它,并且整个应用程序被强制使用easyJson生成的代码。

请参考playground示例:https://play.golang.org/p/VkMFSaq26Oc

我在这里尝试实现的目标是:

  1. if isEasyJsonEnabled {
  2. easyjson.Unmarshal(inp1, inp2)
  3. } else{
  4. json.Unmarshal(inp1, inp2)
  5. }

如你在playground代码中所见,上述条件不起作用:两个解组器都将使用easyJson代码。请在这里指导我或建议是否需要其他信息。

英文:

While doing a POC with JSON unmarshalling I need to use two custom json providers based on some condition in my go code.

  1. easyJson.unmarshal()
  2. json.unmarshal()

Problem I am facing is as we have a custom easyJson code imported, json.Unmarshal() will also be using that and complete application is forced to use the easyJson generated code.

Refer playground example: https://play.golang.org/p/VkMFSaq26Oc

What I am trying to achieve here is

  1. if isEasyJsonEnabled {
  2. easyjson.Unmarshal(inp1, inp2)
  3. } else{
  4. json.Unmarshal(inp1, inp2)
  5. }

Above condition is not working as you can see in the playground code: both unmarshallers will use the easyJson code. Guide me here or suggest if any other info needed here.

答案1

得分: 2

你可以创建一个包装你当前类型的新的不同类型。

类似于以下代码:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os"
  6. )
  7. type Foo struct {
  8. Bar string `json:"bar"`
  9. }
  10. type Bar Foo
  11. // UnmarshalJSON 实现了自定义的解析器,类似于 easyjson 自动生成的解析器。
  12. // 这是一个假设的情况,用于演示当我们使用 encoding/json.Unmarshal 时,UnmarshalJSON 会自动调用的情况。
  13. //
  14. // 尝试注释掉这个方法,看看有什么不同!
  15. func (f *Foo) UnmarshalJSON(b []byte) error {
  16. f.Bar = "我正在使用自定义解析器!"
  17. return nil
  18. }
  19. func main() {
  20. var f Foo
  21. b := []byte(`{"bar":"fizz"}`)
  22. var bar Bar
  23. err := json.Unmarshal(b, &bar)
  24. if err != nil {
  25. fmt.Println("ERR:", err)
  26. os.Exit(1)
  27. }
  28. f = Foo(bar)
  29. fmt.Printf("Result: %+v", f)
  30. }
英文:

You can make a new distinct type that wraps your current type.

Something like

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os"
  6. )
  7. type Foo struct {
  8. Bar string `json:"bar"`
  9. }
  10. type Bar Foo
  11. // UnmarshalJSON implements custom unmarshaler, similar to the one generated by easyjson.
  12. // This is a hypotethical case to demonstrate that UnmarshalJSON is automatically called
  13. // when we are using encoding/json.Unmarshal.
  14. //
  15. // Try commenting this method and see the difference!
  16. func (f *Foo) UnmarshalJSON(b []byte) error {
  17. f.Bar = "I'm using custom unmarshaler!"
  18. return nil
  19. }
  20. func main() {
  21. var f Foo
  22. b := []byte(`{"bar":"fizz"}`)
  23. var bar Bar
  24. err := json.Unmarshal(b, &bar)
  25. if err != nil {
  26. fmt.Println("ERR:", err)
  27. os.Exit(1)
  28. }
  29. f = Foo(bar)
  30. fmt.Printf("Result: %+v", f)
  31. }

huangapple
  • 本文由 发表于 2021年6月20日 14:50:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/68053355.html
匿名

发表评论

匿名网友

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

确定