Hacker News new | past | comments | ask | show | jobs | submit login
Small introduction to tags in Go (machiel.me)
75 points by SerialMiller on July 21, 2015 | hide | past | favorite | 15 comments



This is what I like about Go. This "small introduction" is basically everything there is to know about struct tags.

Bonus, Gorethink tags [0] and how we use them at Lavaboom [1].

0: https://github.com/dancannon/gorethink#encodingdecoding-stru...

1: https://github.com/lavab/api/tree/master/models


At GopherCon, Kyle Erf and Sam Helman gave a great talk about struct tags, how some people are currently using them.

SourceGraph did a write up that summarized it very nicely. https://sourcegraph.com/blog/live/gophercon2015/123669868275


the official GopherCon videos aren't posted yet, but you can find a recording of this talk here: https://www.youtube.com/watch?v=JVc-dTyXDAs


Why is this "tag" system considered a good feature? It seems so arbitrary. It's used exclusively for reflective logic which should instead be done at compile-time via a macro system or a system like Template Haskell, which would generate instances like `ToJson`/`FromJson` for a given struct. As the article mentions, Go tags are similar to Java annotations: a mis-feature motivated by the absence of a macro system.


You're right that reflection and compile time code generation are somewhat "dual" in the sense that you can often implement a feature using one or the other.

But that doesn't mean everyone should make the same choice. Go doesn't have macros or templates. It would make the language much larger and many Go development tools would have to be modified to deal with the complexity. This is a minimal language tweak that was far easier to implement, and devtools that don't care about tags can ignore them.


Java annotations can be processed during compilation.


tags are just strings. there is no spec tag whatsoever or syntax that can be validated at compile time.

A better solution would have been a proper annotation system that is part of the spec.


This is the one problem.

Spent a whole day trying to figure out why only the first tag in the struct was 'active':

  Name string `xml:"name", db:"name"`  //<--- XML works, DB doesn't

  Name string `db:"name", xml:"name"`  //<--- DB works, XML doesn't
The answer was, going from memory, I added a comma (,) between the tags. Should have been:

  Name string `xml:"name" db:"name"`
Stupid simple mistake, but really hard to track down. There was no compiler error, the second tag failed silently, and the first tag worked, so it was really hard to find the bad code.

That along with my favorite: quote-wars. Many-a-time did I forget the quotes on the tag itself only to have it fail (without warning again...):

  Name string `xml:name db:"name"` //<--- DB works, XML doesn't


The `go vet` tool will find these issues. Not ideal, but it will catch tag strings that compile but incorrectly formatted.

http://godoc.org/golang.org/x/tools/cmd/vet


> Stupid simple mistake, but really hard to track down. There was no compiler error, the second tag failed silently, and the first tag worked, so it was really hard to find the bad code.

IMHO, this is why encoding meta-information into strings fail in every incarnation I've experienced. For a retro example, we need look no further than the various data base libraries which place the SQL in strings.

Bad things happen when the compiler is crippled by "tunneling" statements through strings.


This should be handy for frameworks to do their own logic, but I would get very annoyed if I had to read code that was cluttered with tags.


Simplicity and minimalism are core values in Go, both in the language itself and the community and developers that use it, so clutter tends not to be a concern.

That aside, tags are currently in use in several ORM frameworks with a fair amount of success.


From experience you don't tend to see tags very often other than when decoding/encoding JSON. If you use an ORM maybe you use tags as well.

Other than that, their usage (at least to me after working with Go for a year now) is limited to things like Toml/YAML decoding for configuration, or (shameless plug) configuration with https://github.com/vrischmann/envconfig.


// VerifyPassword checks if password is valid and upgrades it if its encrypting scheme was outdated // Returns isValid, wasUpdated, error

func (a *Account) VerifyPassword(password string) (bool, bool, error) {

this is why we need sum types people


or just named return values

  func (a *Account) VerifyPassword(password string) (isValid, wasUpdated bool, err error) {




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: