cool breeze
cool breeze

Reputation: 4811

Is metadata or attributes allowed in Golang?

How are these various validation libraries adding this meta data to structs like:

type Post struct {
    Title    string `valid:"alphanum,required"`
    Message  string `valid:"duck,ascii"`
    AuthorIP string `valid:"ipv4"`
    Date     string `valid:"-"`
}

I'm confused, the property is Title, the type is string. Beyond that how can you just add valid:"alphanum,required" Is this using reflection?

Is this like attributes in other languages?

[Required]
public int Title { get;set; }

Upvotes: 6

Views: 7153

Answers (2)

InkyDigits
InkyDigits

Reputation: 3228

Those are tags. From the language spec (towards the end of 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. The tags are made visible through a reflection interface and take part in type identity for structs but are otherwise ignored.

As per the quote above, you can use them with reflection.

ALso , from the reflect package doc:

A StructTag is the tag string in a struct field.

By convention, tag strings are a concatenation of optionally space-separated key:"value" pairs. Each key is a non-empty string consisting of non-control characters other than space (U+0020 ' '), quote (U+0022 '"'), and colon (U+003A ':'). Each value is quoted using U+0022 '"' characters and Go string literal syntax.

There is an excellent executable example at the link above.

Tags are also used extensively with json. From the json package docs:

The object's default key string is the struct field name but can be specified in the struct field's tag value. The "json" key in the struct field's tag value is the key name, followed by an optional comma and options.

Loads of additional data on that page.

This earlier question may also be helpful.

Upvotes: 2

Ainar-G
Ainar-G

Reputation: 36279

Go doesn't have attributes in general sense. The strings in the struct are struct tags:

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. The tags are made visible through a reflection interface and take part in type identity for structs but are otherwise ignored.

// A struct corresponding to the TimeStamp protocol buffer.
// The tag strings define the protocol buffer field numbers.
struct {
    microsec  uint64 "field 1"
    serverIP6 uint64 "field 2"
    process   string "field 3"
}

You can't add or change them, but you can access them using the reflect package.

Another thing that kinda looks like attributes are "magic comments" like

// +build amd64

or

//go:noinline

These are compiler-specific and IIRC are not a part of the language specification.

Upvotes: 5

Related Questions