Struct Tags
Go struct tags are annotations that appear after the type in a Go struct declaration. Each tag is composed of short strings associated with some corresponding value.
A struct tag looks like this, with the tag offset with backtick “ characters:
type User struct {
Name string `example:"name"`
}
We can write other go code to examine the tags and do some cool stuff with it. The tags don’t change the main go struct behavior.
How to get environment variable value by the struct tags?
The classic example of populating the struct fields by the environment variable is by doing os.Getenv() again and again and manually populating the values. But in this case the work is to much repeat and error prone if the struct is too large.
type EmailConfig struct {
Email string `env:"EMAIL"`
}
func main() {
cfg := EmailConfig{
Email: os.Getenv("EMAIL")
}
}
But can we improve it? Yes we can by using the reflection
import (
"fmt"
"os"
"reflect"
)
type Config struct {
Email string `env:"EMAIL"`
}
const tagName = "env"
func LoadConfig(q *Config) {
v := reflect.ValueOf(q).Elem()
if v.Kind() == reflect.Struct {
val := reflect.TypeOf(q).Elem()
for i := 0; i < val.NumField(); i++ {
field := val.Field(i)
tag := field.Tag.Get(tagName)
fmt.Printf("field : %v | tagName : %v\n", field.Name, tag)
envVal := os.Getenv(tag)
reflect.ValueOf(q).Elem().FieldByName(field.Name).Set(reflect.ValueOf(envVal))
}
}
}
func main() {
var cfg Config
LoadConfig(&cfg)
fmt.Println(cfg)
}
- Here we have initiated a empty cfg structs and passed the reference in the LoadConfig function.
- In the LoadConfig function we have iterated over the struct field.
- we extract the tag fields and set the field values with the environment variable value extracted by the tag name.