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


GOLANG Solutions, GO

Author: Tuan Nguyen
Reviewer: Deepak Prasad

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

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

 

Views: 378
Tuan Nguyen

Tuan Nguyen

He is proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise spanning these technologies, he develops robust solutions and implements efficient data processing and management strategies across various projects and platforms. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

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 send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment