

Small introduction to tags in Go - SerialMiller
https://machiel.me/using-tags-in-go/

======
simi_
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...](https://github.com/dancannon/gorethink#encodingdecoding-structs)

1:
[https://github.com/lavab/api/tree/master/models](https://github.com/lavab/api/tree/master/models)

------
MikeKusold
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](https://sourcegraph.com/blog/live/gophercon2015/123669868275)

~~~
packetslave
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](https://www.youtube.com/watch?v=JVc-dTyXDAs)

------
jamesfisher
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.

~~~
skybrian
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.

------
aikah
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.

~~~
toufka
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

~~~
biggc
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](http://godoc.org/golang.org/x/tools/cmd/vet)

------
quibit
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.

~~~
Zikes
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.

------
asdfasdfasjkl
// 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

~~~
chrisbroadfoot
or just named return values

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

