How to set default values in GO structs? [SOLVED]


Written By - Tuan Nguyen
Advertisement

In today's post, I will introduce some techniques and methods to set default values ​​in Go structs. We already have some articles about structs, marshal, unmarshal, and constants in structs,... you can refer to these posts to deeply understand how to work with structs in Golang.

 

Method 1: Using a separate constructor function for the structs

The idea is quite simple. We will create a function that returns a struct with some default value.

package main

import "fmt"

type Student struct {
	Name   string
	School string
	Age    int
}

// Set default value for a instance
func SetDefault(name string) Student {
	st := Student{}
	st.Name = name
	st.School = "Go LinuxCloud"
	st.Age = 25
	return st
}

func main() {
	defaultStudent := SetDefault("Harry Potter")
	fmt.Printf("The default student: %+v\n", defaultStudent)

	student := new(Student)
	fmt.Printf("The empty student: %+v\n", student)
}

Output:

The default student: {Name:Harry Potter School:Go LinuxCloud Age:25}
The empty student: &{Name: School: Age:0}

 

Method 2: Using an Init() function

The idea for this method is to create an Init() function for that struct. The code below shows how we can do that in Golang:

package main

import "fmt"

type Student struct {
	Name   string
	School string
	Age    int
}

// Init is the main function that initiate the structure, and return it
func (st Student) Init() Student {
	st.Name = "Default Value"
	st.School = "Go LinuxCloud"
	st.Age = 25
	return st
}

func main() {
	defaultStudent := new(Student).Init()
	fmt.Printf("The default student: %+v\n", defaultStudent)
}

Output:

The default student: {Name:Default Value School:Go LinuxCloud Age:25}

 

Method 3: Set struct default value using struct tags

Tags offer a method of doing this that enables multiple defaults. Suppose you have the struct below, which has the default tags default0 and default1. We will try to create 2 default structs in the example below:

package main

import (
	"fmt"
	"reflect"
	"strconv"
)

type Student struct {
	Name   string `default0:"Harry Potter" default1:"Custom Name"`
	School string `default0:"GoLinuxCloud" default1:"Google"`
	Age    int    `default0:"3" default1:"42"`
}

func main() {
	std1 := &Student{}
	Set(std1, "default0")
	fmt.Printf("The first default value: %+v\n", std1)

	std2 := &Student{}
	Set(std2, "default1")
	fmt.Printf("The second default value: %+v\n", std2)
}

func setField(field reflect.Value, defaultVal string) error {

	if !field.CanSet() {
		return fmt.Errorf("Can't set value\n")
	}

	switch field.Kind() {

	case reflect.Int:
		if val, err := strconv.ParseInt(defaultVal, 10, 64); err == nil {
			field.Set(reflect.ValueOf(int(val)).Convert(field.Type()))
		}
	case reflect.String:
		field.Set(reflect.ValueOf(defaultVal).Convert(field.Type()))
	}

	return nil
}

func Set(ptr interface{}, tag string) error {
	if reflect.TypeOf(ptr).Kind() != reflect.Ptr {
		return fmt.Errorf("Not a pointer")
	}

	v := reflect.ValueOf(ptr).Elem()
	t := v.Type()

	for i := 0; i < t.NumField(); i++ {
		if defaultVal := t.Field(i).Tag.Get(tag); defaultVal != "-" {
			if err := setField(v.Field(i), defaultVal); err != nil {
				return err
			}

		}
	}
	return nil
}

Output:

The first default value: &{Name:Harry Potter School:GoLinuxCloud Age:3}
The second default value: &{Name:Custom Name School:Google Age:42}

Explanation

Advertisement

We will create 2 helper functions: Set() and SetField(). These two functions will iterate all the fields in the struct and set the value in the tag to each field.

 

Summary

A constructor function can be used to give default values to a struct. Instead of explicitly building a structure, we may use a constructor to give all or some of its members custom default values.

 

References

https://pkg.go.dev/encoding/json
How to set default values in Go structs - Stack Overflow

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment