Have you run into an elaborate struct definition with a struct
inside a struct
? Or, has someone told you to โuse an inline struct definitionโ?
If youโre not sure how to approach any of this, then youโre in the right place.
This article will discuss anonymous structs: what they are and when to consider using them.
What is an anonymous struct?
You probably know that you can define struct types using a type definition:
This is the typical way to define struct types. It forces you to name the struct type, in the above example the name of our struct type is Album
.
This name can then be used in every place where Go accepts a type. A variable declaration for example:
However, this is not the only way to define struct types. You can also define them anonymously, without giving them a name.
Go will still need to know the exact โshapeโ of your struct, you will need to provide the entire struct definition in place of a name to use an anonymous struct.
This is sometimes referred to as "defining a struct inline".
If we define our a new variable with an anonymous struct type, it looks like this:
This code places the entire struct{...}
definition where the Album
name was in the earlier declaration.
In both examples, the variables are assigned zero values by default. Weโre not assigning any initial values.
The zero value for a struct will be the struct with all fields set to their zero values.
If we do assign an initial value you will see that anonymous structs can lead to some repetitive code.
First, letโs look how it looks when we assign with a named struct.
This is probably somewhat familiar. Now letโs look at the same assignment using an anonymous struct.
Thatโs quite repetitive. If we miss the second struct{...}
type identifier, we will get syntax errors like:
Luckily we can skip the first struct{...}
type identifier by using the :=
short assignment statement.
Below are some more examples that show how anonymous contexts look in different contexts.
Example: Slice element
This example shows an anonymous struct as a slice element. Just like with other types, itโs not necessary to repeat the type for each slice element.
Example: Map element
This example shows an anonymous struct as a map element. Again, itโs not required to repeat the type for each element.
Example: Struct field
In this example you can see a named struct with an anonymous inner struct. Just like with our initial variable assignments we now need to specify the inner type definition again.
When to use anonymous structs?
As far as I tell there is no technical reason to use anonymous structs, they wonโt make your programs more efficient.
All their value is due to what they communicate to other developers or readers of your source code.
Anonymous structs are a way to emphasize that a data type is only relevant in a very specific situation. A situation so specific, that a single type definition is all you need.
If you end up having to repeat the anonymous struct definition in multiple places, itโs likely a lot easier to use a named definition.
Common uses
If this all seems somewhat vague, wellโฆ it is. How/when to use anonymous structs is mostly a matter of taste and can differ between code bases and developers.
In my experience, there are two relatively common patterns that use anonymous structs
1. Table tests
Table tests are a way to organize your test data inside a โtableโ.
The โtableโ consists of columns that contain input and expected output for the function that is being tested. These columns are usually highly specific to this function, itโs not uncommon for every โtableโ to be structured differently.
For example, suppose weโre testing a function called Add
that adds two integers x
and y
, we might have test cases like this:
x | y | wanted result |
---|---|---|
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 2 |
-1 | 0 | -1 |
0 | -1 | -1 |
-1 | -1 | -2 |
A very common way to implement these โtablesโ is using a map or slice with an anonymous struct as its element type. The example below uses a slice.
Anonymous structs are suitable because these โtablesโ are highly specific to the function that is being tested. If you would use named types they would likely only see a single use.
2. One-off unmarshalling targets
Sometimes you will need to map formatted data to a function. It can be useful to have an intermediate struct to unmarshal the formatted data into.
If this unmarshalling is only done in a single place in your source code, an anonymous struct be a suitable data type for this intermediate struct.
For example, letโs say that weโre creating a HTTP handler that maps JSON to a function call. In this case, weโre mapping a message
and number
to the doSomething
function.
In this example the args
struct is used as an โinbetweenโ unmarshalling target. Since there is no need to reuse it, itโs not exposed outside of the handler.
There is a balance to be reached here, if the number of fields gets unwieldy you might want to have the function accept a named struct type instead.
Outro
I hope this article gives you some insight into anonymous structs. We discussed:
- The syntax for anonymous structs.
- Their value is in communication, not anything technical.
- Two common use cases: Table tests and unmarshalling targets.
If you have any questions or comments, feel free to reach out to me :)



Get my free newsletter periodically*
Used by 500+ developers to boost their Go skills.
*working on a big project as of 2025, will get back to posting on the regular schedule once time allows.
