Struct tags

March 17, 2023

Struct types

A field declaration may be followed by an optional string literal tag, which becomes an attribute for all the fields in the corresponding field declaration. An empty tag string is equivalent to an absent tag. The tags are made visible through a reflection interface and take part in type identity for structs but are otherwise ignored.

struct {
	x, y float64 ""  // an empty tag string is like an absent tag
	name string  "any string is permitted as a tag"
	_    [4]byte "ceci n'est pas un champ de structure"

// A struct corresponding to a TimeStamp protocol buffer.
// The tag strings define the protocol buffer field numbers;
// they follow the convention outlined by the reflect package.
struct {
	microsec  uint64 `protobuf:"1"`
	serverIP6 uint64 `protobuf:"2"`

Struct tags are many things. Confusing. Slightly magical. Powerful. Abused. Probably a few other things as well.

While any string is permitted as a tag (as shown in the example above), by convention they should conform to the format understood by reflect.StructTag, and any that don’t will cause go vet to complain.

You’ll most frequently see struct tags used to indicate a field’s name in an alternative representation, such as when expressed in JSON, YAML, or in a corresponding database table. You may even see them combined:

type Person struct {
	Name     string `json:"name" db:"name"`
	Age      int    `json:"age" db:"age"`
  Password string `json:"-" db:"pass"`

You may also interpret your own arbitrary struct tags by using the reflection library. And while you can use tags in any format, it’s worth stressing that you should stick to the format understood by reflect.StructTag, otherwise you’ll earn the ire of every other Go developer who has to use your (in their eyes) broken code!

Quotes from The Go Programming Language Specification Version of December 15, 2022

Share this

Related Content

Empty structs

We finally we have enough knowledge for the EBNF format not to seem completely foreign, so let’s jump back and take a look at that, with the examples provided in the spec… Struct types … StructType = "struct" "{" { FieldDecl ";" } "}" . FieldDecl = (IdentifierList Type | EmbeddedField) [ Tag ] . EmbeddedField = [ "*" ] TypeName [ TypeArgs ] . Tag = string_lit . // An empty struct.

Struct method promotion

Yesterday we saw an example of struct field promotion. But methods (which we haven’t really discussed yet) can also be promoted. Struct types … Given a struct type S and a named type T, promoted methods are included in the method set of the struct as follows: If S contains an embedded field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.

Struct field promotion

Yesterday we learned that structs can have embedded fields. Although we didn’t really learn about any of the special powers this gives us. Today we’ll have a look at those powers. One advantage to using an embedded type is that the implicit field name (the one derrived from the type, Person, in our example) can be omitted. This is the result of “promotion”. For example: var e Employee e.Name = "Bob" // equivalent to e.