Things Developers Miss From Other Languages
Latest update: March 26, 2023

Things Developers Miss From Other Languages #

Annotations #

Annotations are something that Java developers are particularly used to. Annotations (e.g @Entity, or @JsonProperty, etc.) are everywhere in Java code. They serve various purposes - from pure basic documentation, to compile-time and run-time code augmentation. Not surprisingly, annotations are sometimes seen as a form of magic - add the right one to a class, and it may completely change its behaviour; sometimes in ways that are difficult to reason about from beginners.

Annotations save a ton of boilerplate code, but they also obscure what is going on under the hood. Thus, as is typical for the rest of Go, annotations are nowhere to be found in the language. This might be quite a shock for newcomers from Java, but it is an intentional omission, in the name of transparency. Thankfully, the language has enough capabilities that allow developers to reduce boilerplate in a similar fashion.

Struct Tags #

Struct tags are a simple way to add metadata to struct fields in the form of tags. This information can be read both in runtime (most often), or during code generation. One example of using struct tags in the daily practice is JSON de/serialization (un/marshaling):

// Playground https://go.dev/play/p/FvXLA3Ajl4O

import (
	"encoding/json"
	"fmt"
	"log"
)

type Person struct {
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
}

// ...
var p Person
err := json.Unmarshal([]byte(`{"first_name": "John", "last_name": "Smith"}`), &p)
	// Check the error!
	// p will now look like this: {FirstName:John LastName:Smith}
}

Struct tags are read with the help of reflection, and the same field can have multiple tags serving different purposes. Many popular libraries make use of those for runtime code augmentation. For instance, the popular ORM-like library GORM is well-known for using struct tags to map SQL result data to structs (roughly mimicking an object graph):

type Account struct {
	ID            uint   `gorm:"primary_key;AUTO_INCREMENT" json:"id"`
	Username      string `gorm:"type:varchar(50);not null;index:user_idx" json:"username"`
	RealName      string `gorm:"type:varchar(50);" json:"real_name"`
	Email         string `gorm:"type:varchar(50);" json:"email"`
}

It is important to note that while useful, struct tags are used way less in Go code than annotations in Java. This is because reflection is generally a less-advised practice among the Go community. If it is something that gets evaluated once during code generation or the loading of the application, it is totally fine, however, a Go developer would usually frown if reflection introspection gets used heavily during runtime (one of the criticisms against GORM).

NOTE: This is temporarily the end of the current section. There will be more on this topic in due time.