Why there are tags in Go?

A small tutorial with code examples about tags in Golang programming language
10 August 2017   1570

Hype.Codes team continues to answer popular technical questions about programming languages. We made a research and found out what tags "do" in Go.

A tag for a field allows you to attach meta-information to the field which can be acquired using reflection. Usually it is used to provide transformation info on how a struct field is encoded to or decoded from another format (or stored/retrieved from a database), but you can use it to store whatever meta-info you want to, either intended for another package or for your own use.

As mentioned in the documentation of reflect.StructTag, by convention the value of a tag string is a space-separated key:"value" pairs, for example:

type User struct {
    Name string `json:"name" xml:"name"`
}

The key usually denotes the package that the subsequent "value" is for, for example jsonkeys are processed/used by the encoding/json package.

If multiple information is to be passed in the "value", usually it is specified by separating it with a comma (','), e.g.

Name string `json:"name,omitempty" xml:"name"`

Usually a dash value ('-') for the "value" means to exclude the field from the process (e.g. in case of json it means not to marshal or unmarshal that field).

Example of accessing your custom tags using reflection

We can use reflection (reflect package) to access the tag values of struct fields. Basically we need to acquire the Type of our struct, and then we can query fields e.g. with Type.Field(i int) or Type.FieldByName(name string). These methods return a value of StructFieldwhich describe / represent a struct field; and StructField.Tag is a value of type StructTagwhich describes / represents a tag value.

Previously we talked about "convention". This convention means that if you follow it, you may use the StructTag.Get(key string) method which parses the value of a tag and returns you the "value" of the key you specify. The convention is implemented / built into this Get() method. If you don't follow the convention, Get() will not be able to parse key:"value" pairs and find what you're looking for. That's also not a problem, but then you need to implement your own parsing logic.

Also there is StructTag.Lookup() (was added in Go 1.7) which is "like Get() but distinguishes the tag not containing the given key from the tag associating an empty string with the given key".

So let's see a simple example:

type User struct {
    Name  string `mytag:"MyName"`
    Email string `mytag:"MyEmail"`
}

u := User{"Bob", "bob@mycompany.com"}
t := reflect.TypeOf(u)

for _, fieldName := range []string{"Name", "Email"} {
    field, found := t.FieldByName(fieldName)
    if !found {
        continue
    }
    fmt.Printf("\nField: User.%s\n", fieldName)
    fmt.Printf("\tWhole tag value : %q\n", field.Tag)
    fmt.Printf("\tValue of 'mytag': %q\n", field.Tag.Get("mytag"))
}

Output :

Field: User.Name
    Whole tag value : "mytag:\"MyName\""
    Value of 'mytag': "MyName"

Field: User.Email
    Whole tag value : "mytag:\"MyEmail\""
    Value of 'mytag': "MyEmail"

CockroachDB to Change License Type

The only restriction in new bundle of licenses is the ban on selling commercial versions of CockroachDB, made in the form of cloud services
05 June 2019   252

The developers of the distributed DBMS CockroachDB have announced the migration of the project source code into a bundle from the Business Source License (BSL) and Cockroach Community License (CCL), which is not free due to the discrimination of certain categories of users. The BSL license was proposed by MySQL co-founders three years ago as an alternative to the Open Core model. The essence of BSL is that the extended functionality code is initially available for making changes, but for a certain period of time it can be used for free only if the additional conditions are met that require a commercial license to be circumvented.

The new license allows the use of CockroachDB on any number of nodes in the cluster and embedding in applications, including those that are sold to customers or run as services. The only restriction that prevents the license from being considered free and open is the ban on selling commercial versions of CockroachDB, made in the form of cloud services. To issue a CockroachDB in the form of paid cloud services now requires the purchase of a commercial license.

As in the case of the re-licensing of MongoDB, Redis and TimescaleDB modules, the reason for the transition to a non-free license is the fight against the parasitization of cloud service providers who create derivative commercial products and resell open DBMS as cloud services but do not participate in the community and do not help in developing. It happens when the cloud providers, who are not related to the project, resell ready-made open solutions and benefit, but the developers are left with nothing.