How to use two JSON unmarshallers in the same project?

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

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

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

if isEasyJsonEnabled {
	 easyjson.Unmarshal(inp1, inp2)
	} else{
     json.Unmarshal(inp1, inp2)     
}

如你在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

if isEasyJsonEnabled {
	 easyjson.Unmarshal(inp1, inp2)
	} else{
     json.Unmarshal(inp1, inp2)     
}

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

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

类似于以下代码:

package main

import (
	"encoding/json"
	"fmt"
	"os"
)

type Foo struct {
	Bar string `json:"bar"`
}

type Bar Foo

// UnmarshalJSON 实现了自定义的解析器,类似于 easyjson 自动生成的解析器。
// 这是一个假设的情况,用于演示当我们使用 encoding/json.Unmarshal 时,UnmarshalJSON 会自动调用的情况。
//
// 尝试注释掉这个方法,看看有什么不同!
func (f *Foo) UnmarshalJSON(b []byte) error {
	f.Bar = "我正在使用自定义解析器!"
	return nil
}

func main() {
	var f Foo
	b := []byte(`{"bar":"fizz"}`)
	
	var bar Bar

	err := json.Unmarshal(b, &bar)
	if err != nil {
		fmt.Println("ERR:", err)
		os.Exit(1)
	}
	f = Foo(bar)
	fmt.Printf("Result: %+v", f)
}
英文:

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

Something like

package main

import (
	"encoding/json"
	"fmt"
	"os"
)

type Foo struct {
	Bar string `json:"bar"`
}

type Bar Foo

// UnmarshalJSON implements custom unmarshaler, similar to the one generated by easyjson.
// This is a hypotethical case to demonstrate that UnmarshalJSON is automatically called
// when we are using encoding/json.Unmarshal.
//
// Try commenting this method and see the difference!
func (f *Foo) UnmarshalJSON(b []byte) error {
	f.Bar = "I'm using custom unmarshaler!"
	return nil
}

func main() {
	var f Foo
	b := []byte(`{"bar":"fizz"}`)
	
	var bar Bar

	err := json.Unmarshal(b, &bar)
	if err != nil {
		fmt.Println("ERR:", err)
		os.Exit(1)
	}
	f = Foo(bar)
	fmt.Printf("Result: %+v", f)
}

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:

确定