If it's a "one way" serialization (for debugging or logging or whatever) then fmt.Printf("%#v", var) is very nice. (Update: to put the output into a string instead of printing it, use str := fmt.Sprintf("%#v", var).

If size matters you can use %v, but I like %#v because it will also include the field names and the name of the struct type.

A third variation is %+v which will include the field names, but not the struct type.

They are all documented at the top of the fmt documentation.

If you need two-way serialization JSON, Gob or XML are the easiest/built-in options in Go, see the encoding packages.

Answer from Ask Bjørn Hansen on Stack Overflow
🌐
Go by Example
gobyexample.com › structs
Go by Example: Structs
Go’s structs are typed collections of fields. They’re useful for grouping data together to form records · This person struct type has name and age fields
Discussions

Why are struct tags strings
The official definition, such as it is, is actually in reflect.StructTag.Get , which specifies the namespacing mechanism unambiguously, albeit by code rather than necessarily a formal grammar. I think possibly the reason is that you're not actually supposed to find them "very useful", and I suspect the "very useful" uses you are putting them to are likely going to prove out to be a bad idea in the end. They're for little tiny annotations. They're not meant to hold vast quantities of information, and that's because with the rest of the design of Go, the metadata they represent becomes frequently sheered away from the data they are nominally annotating, becoming useless, or even worse than useless. Let me give a concrete example. Let's say you've got a structure with a time.Time in it, but you decide you want a different format to come out. So you decorate the time.Time with a struct tag that gives the format: type SomeStruct struct { StartTime time.Time `time:"Mon Jan _2 15:04:05 MST 2006"` } Already we've encountered a problem with struct tags, which is that they are not expressions and as such have no access to constants; can't just set it to time.UnixDate. But moving on. We can hack up a JSON parser that uses this to format the dates on the way in and out. (This doesn't exist, but it would be easy to add to an existing one.) But as soon as the StartTime leaves the context of the struct, it also leaves the struct tag behind. Once you pass it to something it's just a time.Time, and the receiver of that type has no ability to use the struct tag. If it serializes it, it'll do whatever it does. A better way to do this sort of thing is the one described in this recent post . This extends out in general. It is likely that what you are trying to stick in struct tags belongs in types in Go. This gets problematic in its own way sometimes because you can't create a parameterized type very easily, though you can get an awfully long way without them. Types have the advantages that the type does stick to the data. Interfaces allow you to interact with these various types polymorphically and write code that doesn't care about those details. The "worse than useless" comment I ended my second paragraph with comes from people who almost get the struct tags to do what they want, but when they run into a problem, do yet crazier things to the code to try to get them to "work", even though they really aren't. There is almost always a better way to deal with these problems and doubling down further on struct tags is unlikely to be a good idea in practice. Struct tags are useful in their own little way but they're also a bit of an attractive nuisance; generally as soon as you encounter any trouble with them you should stop using them and pursue the question of whether you can solve your problem with types instead. If you'd like to post a specific example of a struct tag that you're trying to use, we can provide concrete advice on whether perhaps you should be using types and what they could be. More on reddit.com
🌐 r/golang
34
70
January 26, 2024
How to group strings into a struct / variable?
I’m not quite sure I understand what you’re designing but for typo-prevention string constants I just declare them all as const ( … ) at the top of the file More on reddit.com
🌐 r/golang
11
6
May 24, 2025
How convert / print struct as a string

Yes, RTFM about the %v and %#v formats supported by the *f family of functions from the fmt standard package.

For more hardcode stuff, look at go-spew.

More on reddit.com
🌐 r/golang
6
2
April 9, 2018
🌐
Go Forum
forum.golangbridge.org › getting help
Convert/Pass the contents of a struct to []String - Getting Help - Go Forum
May 12, 2020 - Hi. New to go. Working with some code, and overview is I would like to convert the contents of a struct, which is holding unmarshalled json into an array so it can be used in an API that only accepts []string format. I have tried various ways of doing this, but being new I’m obviously missing something simple. i.e. struct type Log struct { CommonLabels CommonLabels json:"commonLabels" } type CommonLabels struct { name string json:"name" note string json:"note" } So I have values in ...
🌐
YourBasic
yourbasic.org › golang › structs-explained
Create, initialize and compare structs · YourBasic Go
yourbasic.org/golang · Struct types · 2 ways to create and initialize a new struct · Compare structs · A struct is a typed collection of fields, useful for grouping data into records. type Student struct { Name string Age int } var a Student ...
🌐
Delft Stack
delftstack.com › home › howto › go › golang struct to string
How to Convert Struct to String in Golang | Delft Stack
February 2, 2024 - The structure I made has the following data: Hello, World! GoLang is fun! The code showcases how to customize a Go struct’s string representation using fmt.Sprintf() and the String() method.
🌐
Reddit
reddit.com › r/golang › why are struct tags strings
r/golang on Reddit: Why are struct tags strings
January 26, 2024 -

I recently learned how to use tags in structs. I find it very useful, but parsing them seems to be unnecessarily difficult.

type Log struct {
    Time time.Time     `db:"ts,s"` 
}

There's a library called structtag that does it for you, but why couldn't this be a native functionality like so:

type Log struct {
    Time time.Time     {"db":["ts", "s"]}
}

What am missing here?

Top answer
1 of 10
53
The official definition, such as it is, is actually in reflect.StructTag.Get , which specifies the namespacing mechanism unambiguously, albeit by code rather than necessarily a formal grammar. I think possibly the reason is that you're not actually supposed to find them "very useful", and I suspect the "very useful" uses you are putting them to are likely going to prove out to be a bad idea in the end. They're for little tiny annotations. They're not meant to hold vast quantities of information, and that's because with the rest of the design of Go, the metadata they represent becomes frequently sheered away from the data they are nominally annotating, becoming useless, or even worse than useless. Let me give a concrete example. Let's say you've got a structure with a time.Time in it, but you decide you want a different format to come out. So you decorate the time.Time with a struct tag that gives the format: type SomeStruct struct { StartTime time.Time `time:"Mon Jan _2 15:04:05 MST 2006"` } Already we've encountered a problem with struct tags, which is that they are not expressions and as such have no access to constants; can't just set it to time.UnixDate. But moving on. We can hack up a JSON parser that uses this to format the dates on the way in and out. (This doesn't exist, but it would be easy to add to an existing one.) But as soon as the StartTime leaves the context of the struct, it also leaves the struct tag behind. Once you pass it to something it's just a time.Time, and the receiver of that type has no ability to use the struct tag. If it serializes it, it'll do whatever it does. A better way to do this sort of thing is the one described in this recent post . This extends out in general. It is likely that what you are trying to stick in struct tags belongs in types in Go. This gets problematic in its own way sometimes because you can't create a parameterized type very easily, though you can get an awfully long way without them. Types have the advantages that the type does stick to the data. Interfaces allow you to interact with these various types polymorphically and write code that doesn't care about those details. The "worse than useless" comment I ended my second paragraph with comes from people who almost get the struct tags to do what they want, but when they run into a problem, do yet crazier things to the code to try to get them to "work", even though they really aren't. There is almost always a better way to deal with these problems and doubling down further on struct tags is unlikely to be a good idea in practice. Struct tags are useful in their own little way but they're also a bit of an attractive nuisance; generally as soon as you encounter any trouble with them you should stop using them and pursue the question of whether you can solve your problem with types instead. If you'd like to post a specific example of a struct tag that you're trying to use, we can provide concrete advice on whether perhaps you should be using types and what they could be.
2 of 10
21
It's to avoid the "inner platform" problem where you end up with either an implementation of LISP or some metaprogramming abomination. These things are literally tags, not some orthogonal programming model. Note that package reflect has functions to parse (wellformed) tags.
Find elsewhere
🌐
Go 101
go101.org › article › string.html
Strings in Go -Go 101
type _string struct { elements *byte // underlying bytes len int // number of bytes }
🌐
Go
go.dev › ref › spec
The Go Programming Language Specification - The Go Programming Language
B0 and B1 are different because they are new types created by distinct type definitions; func(int, float64) *B0 and func(x int, y float64) *[]string are different because B0 is different from []string; and P1 and P2 are different because they are different type parameters. D0[int, string] and struct{ x int; y string } are different because the former is an instantiated defined type while the latter is a type literal (but they are still assignable).
🌐
Go 101
go101.org › article › struct.html
Structs in Go -Go 101
struct { Title string `json:"title" myfmt:"s1"` Author string `json:"author,omitempty" myfmt:"s2"` Pages int `json:"pages,omitempty" myfmt:"n1"` X, Y bool `myfmt:"b1"` }
🌐
GitHub
gist.github.com › miguelmota › 04252b346d281b93f047bf9a20f73f04
Golang JSON Marshal (struct to string) (M for "Make json") and Unmarshal (string to struct) (U for "Unmake json") example · GitHub
Golang JSON Marshal (struct to string) (M for "Make json") and Unmarshal (string to struct) (U for "Unmake json") example - json_marshal_unmarshal.go
🌐
Reddit
reddit.com › r/golang › how to group strings into a struct / variable?
r/golang on Reddit: How to group strings into a struct / variable?
May 24, 2025 -

Is there a shorter/cleaner way to group strings for lookups? I want to have a struct (or something similar) hold all my DB CRUD types in one place. However I find it a little clunky to declare and initialize each field separately.

var CRUDtype = struct {
    CreateOne                string
    ReadOne                  string
    ReadAll                  string
    UpdateOneRecordOneField  string
    UpdateOneRecordAllFields string
    DeleteOne                string
}{
    CreateOne:                "createOne",
    ReadOne:                  "readOne",
    ReadAll:                  "readAll",
    UpdateOneRecordOneField:  "updateOneRecordOneField",
    UpdateOneRecordAllFields: "updateOneRecordAllFields",
    DeleteOne:                "deleteOne",
}

The main reason I'm doing this, is so I can confirm everywhere I use these strings in my API, they'll match. I had a few headaches already where I had typed "craete" instead of "create", and doing this had prevented the issue from reoccurring, but feels extra clunky. At this point I have ~8 of these string grouping variables, and it seems like I'm doing this inefficiently.

Any suggestions / feedback is appreciated, thanks!

Edit - Extra details:

One feature I really like of doing it this way, is when I type in "CRUDtype." it gives me a list of all my available options. And if pick one that doesn't exist, or spell it wrong, I get an immediate clear compiler error.

🌐
Go Packages
pkg.go.dev › strings
strings package - strings - Go Packages
Size returns the original length of the underlying string. Size is the number of bytes available for reading via Reader.ReadAt. The returned value is always the same and is not affected by calls to any other method. ... UnreadByte implements the io.ByteScanner interface. ... UnreadRune implements the io.RuneScanner interface. func (r *Reader) WriteTo(w io.Writer) (n int64, err error) WriteTo implements the io.WriterTo interface. type Replacer struct { // contains filtered or unexported fields }
🌐
W3Schools
w3schools.com › go › go_struct.php
Go Struct
package main import ("fmt") type Person struct { name string age int job string salary int } func main() { var pers1 Person var pers2 Person // Pers1 specification pers1.name = "Hege" pers1.age = 45 pers1.job = "Teacher" pers1.salary = 6000 // Pers2 specification pers2.name = "Cecilie" pers2.age = 24 pers2.job = "Marketing" pers2.salary = 4500 // Access and print Pers1 info fmt.Println("Name: ", pers1.name) fmt.Println("Age: ", pers1.age) fmt.Println("Job: ", pers1.job) fmt.Println("Salary: ", pers1.salary) // Access and print Pers2 info fmt.Println("Name: ", pers2.name) fmt.Println("Age: ", pers2.age) fmt.Println("Job: ", pers2.job) fmt.Println("Salary: ", pers2.salary) }
🌐
Medium
medium.com › @prashant2018 › parse-json-string-to-struct-object-in-golang-59d3cf6bce7
Parse json string to struct in Golang | by Prashant Kumar | Medium
January 26, 2023 - type Person struct { Name string `json:"name"` Age int64 `json:"age"` Hobbies []string `json:"hobbies"` }
🌐
Go Tutorial
golangbot.com › structs
Golang Structs Tutorial with Examples | golangbot.com
September 8, 2025 - Hence firstName and lastName are assigned the zero values of string which is an empty string "" and age, salary are assigned the zero values of int which is 0. This program prints, ... It is also possible to specify values for some fields and ignore the rest. In this case, the ignored fields are assigned zero values. 1package main 2 3import ( 4 "fmt" 5) 6 7type Employee struct { 8 firstName string 9 lastName string 10 age int 11 salary int 12} 13 14func main() { 15 emp5 := Employee{ 16 firstName: "John", 17 lastName: "Paul", 18 } 19 fmt.Println("First Name:", emp5.firstName) 20 fmt.Println("Last Name:", emp5.lastName) 21 fmt.Println("Age:", emp5.age) 22 fmt.Println("Salary:", emp5.salary) 23}
🌐
DigitalOcean
digitalocean.com › community › tutorials › how-to-use-struct-tags-in-go
How To Use Struct Tags in Go | DigitalOcean
March 24, 2026 - This example defines a User type with a Name field. The Name field has been given a struct tag of example:"name". We would refer to this tag by its key, example, which has the value "name". On the User type, we also define the String() method required by the fmt.Stringer interface.
🌐
Technical Feeder
technicalfeeder.com › 2022 › 12 › golang-converting-struct-to-string
Golang Converting struct to string | Technical Feeder
March 10, 2023 - Do you want to convert struct to string to write the information to the log file? Let's start with simple data type first and then, convert struct data type!