Manually create json object from struct in golang
In golang, manually creating a json object from a struct is a common operation. By converting struct to json format, we can easily use it in network transmission or storage. In this article, PHP editor Banana will introduce you how to use golang's built-in package to achieve this function. Not only that, we will also explore how to deal with nested fields in structs and how to deal with special types of fields. Whether you are a beginner or an experienced developer, this article will provide you with detailed guidance to help you easily create json objects in golang. let's start!
Question content
I have a structure to say
<code>type Foo struct { A string `json:",omitemtpy" } </code>
I know I can easily convert it to json using something like this
json.Marshal(Foo{})
It will return an empty json string.
But I need to use the same structure to return the json representation of the structure with all the fields and "null values" present in the json. (Actually, it's a very large structure, so I can't just keep a copy without tags)
What's the easiest way?
Basically, I need to create a json marshal of a structure that ignores the json omitempty tag.
This json creation does not need to be efficient or performant.
I would have preferred a library for this kind of task, but most libraries I've seen either create some special format or respect omitempty
edit:
Choose https://stackoverflow.com/a/77799949/2187510 as my answer and do some extra work to allow default values (using its code as a reference)
defaultFoo := FoodWithPts{ Str: "helloWorld"} dupFooType := dupType(reflect.TypeOf(defaultFoo)) foo := reflect.Zero(dupFooType).Interface() // New additions defaults, _ := json.Marshal(defaultFoo) json.Unmarshal(defaults, &foo) // overwrites foo with defaults // End New additions data, err := json.Marshal(foo) fmt.Println("dup FooWithPtrs:\n", string(data), err)
Output:
dup FooWithPtrs: {"String":"helloWorld","Int":0,"Bar":null} <nil>
Workaround
You cannot modify tags at runtime, but you can use $$c to create struct types at runtime$$reflect.StructOf().
So the idea is to copy the struct type but exclude the ,omitempty
option from the JSON tag in the duplication.
You can find all examples below on Go Playground.
This is easier than people first think. We just need to do it recursively (one struct field might be another struct), and we should definitely deal with pointers:
func dupType(t reflect.Type) reflect.Type { if t.Kind() == reflect.Pointer { return reflect.PointerTo(dupType(t.Elem())) } if t.Kind() != reflect.Struct { return t } var fields []reflect.StructField for i := 0; i < t.NumField(); i++ { sf := t.Field(i) sf.Type = dupType(sf.Type) // Keep json tag but cut ,omitempty option if exists: if tag, _ := strings.CutSuffix(sf.Tag.Get("json"), ",omitempty"); tag == "" { sf.Tag = "" } else { sf.Tag = `json:"` + reflect.StructTag(tag) + `"` } fields = append(fields, sf) } return reflect.StructOf(fields) }
Let's test it with this type:
type Foo struct { Str string `json:"String,omitempty"` Int int `json:",omitempty"` Bar struct { Float float64 `json:",omitempty"` PtrInt int `json:",omitempty"` Baz struct { X int `json:"XXXX,omitempty"` } `json:",omitempty"` } `json:",omitempty"` }
First, here is the JSON output without type duplication:
data, err := json.Marshal(Foo{}) fmt.Println("Foo:\n", string(data), err)
Output:
Foo: {"Bar":{"Baz":{}}} <nil>
Note that we get the Bar
and Baz
fields because they are structs.
Let’s try type copy:
dupFooType := dupType(reflect.TypeOf(Foo{})) foo := reflect.Zero(dupFooType).Interface() data, err := json.Marshal(foo) fmt.Println("dup Foo:\n", string(data), err)
This will output:
dup Foo: {"String":"","Int":0,"Bar":{"Float":0,"PtrInt":0,"Baz":{"XXXX":0}}} <nil>
good! Exactly what we wanted!
But we're not done yet. What if we have a type with a structure pointer field? like this:
type FooWithPtrs struct { Str string `json:"String,omitempty"` Int int `json:",omitempty"` Bar *struct { Float float64 `json:",omitempty"` PtrInt int `json:",omitempty"` Baz *struct { X int `json:"XXXX,omitempty"` } `json:",omitempty"` } `json:",omitempty"` }
Attempt to JSON marshal values of repeated types:
dupFooType := dupType(reflect.TypeOf(FooWithPtrs{})) foo := reflect.Zero(dupFooType).Interface() data, err := json.Marshal(foo) fmt.Println("dup FooWithPtrs:\n", string(data), err)
Output:
dup FooWithPtrs: {"String":"","Int":0,"Bar":null} <nil>
If the structure contains pointers, these pointers appear in the JSON output as null
, but we would like their fields to appear in the output as well. This requires them to be initialized to non-nil
values in order for them to produce output.
Fortunately, we can also use reflection to do this:
func initPtrs(v reflect.Value) { if !v.CanAddr() { return } if v.Kind() == reflect.Pointer { v.Set(reflect.New(v.Type().Elem())) v = v.Elem() } if v.Kind() == reflect.Struct { for i := 0; i < v.NumField(); i++ { initPtrs(v.Field(i)) } } }
We are excited! Let’s see it in action:
dupFooType := dupType(reflect.TypeOf(FooWithPtrs{})) fooVal := reflect.New(dupFooType) initPtrs(fooVal.Elem()) data, err := json.Marshal(fooVal.Interface()) fmt.Println("dup and inited FooWithPtrs:\n", string(data), err)
Output:
dup and inited FooWithPtrs: {"String":"","Int":0,"Bar":{"Float":0,"PtrInt":0,"Baz":{"XXXX":0}}} <nil>
good! It contains all fields!
The above is the detailed content of Manually create json object from struct in golang. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Since its inception in 2009, Bitcoin has become a leader in the cryptocurrency world and its price has experienced huge fluctuations. To provide a comprehensive historical overview, this article compiles Bitcoin price data from 2009 to 2025, covering major market events, changes in market sentiment, and important factors influencing price movements.

1. First, right-click on the blank space of the taskbar at the bottom of Windows 11 and select [Taskbar Settings]. 2. Find [taskbarcorneroverflow] on the right in the taskbar settings. 3. Then find [clock] or [Clock] above it and select to turn it on. Method 2: 1. Press the keyboard shortcut [win+r] to call up run, enter [regedit] and press Enter to confirm. 2. Open the registry editor, find [HKEY_CURRENT_USERControlPanel] in it, and delete it. 3. After deletion, restart the computer and you will be prompted for configuration. When you return to the system, the time will be displayed.

How do I use other people's Python code? Find code repositories: Find the code you need on platforms like PyPI and GitHub. Installation code: Use pip or clone the GitHub repository to install. Import modules: Use the import statement in your script to import installed modules. Working with code: Access functions and classes in modules. (Optional) Adapt the code: Modify the code as needed to fit your project.

What should I do if the time on my win11 computer is always wrong? We all set the time or calendar when using win11 system, but many users are asking that the computer time is always wrong, so what is going on? Users can directly click on the taskbar below, and then find taskbarcorneroverflow to set it up. Let this site introduce to users in detail how to adjust the time error on Win11 computers. How to adjust the computer time error in Windows 11. Method 1: 1. We first right-click on the blank space of the taskbar below and select Taskbar Settings. Method 2: 1. Press the keyboard shortcut win+r to call up run, enter regedit and press Enter to confirm.

Common exception types and their repair measures in Java function development During the development of Java functions, various exceptions may be encountered, which affect the correct execution of the function. The following are common exception types and their repair measures: 1. NullPointerException Description: Thrown when accessing an object that has not been initialized. Fix: Make sure you check the object for non-null before using it. Sample code: try{Stringname=null;System.out.println(name.length());}catch(NullPointerExceptione){

As a world-renowned short video platform, Douyin has a huge user base and content creators. However, as the platform rules are constantly updated and improved, some users may encounter account bans. This has raised public questions about the transparency and fairness of platform management. This article will discuss the issue of Douyin account bans and whether users have ways to appeal after their accounts are banned. There may be many reasons for being banned on the Douyin platform, including but not limited to illegal content, violation of platform regulations, infringement of other people's rights, etc. In order to maintain the order of the platform and the interests of users, Douyin has set up a series of rules and review mechanisms. When some users violate the rules, their accounts may be banned. However, some users may question or be dissatisfied with the reasons for the ban

Exception handling in recursive calls: Limiting recursion depth: Preventing stack overflow. Use exception handling: Use try-catch statements to handle exceptions. Tail recursion optimization: avoid stack overflow.

The following techniques are available for debugging recursive functions: Check the stack traceSet debug pointsCheck if the base case is implemented correctlyCount the number of recursive callsVisualize the recursive stack
