How to Use Structs in GoLang: A Comprehensive Tutorial
This blog post discussed structs in GoLang, which are user-defined types used to group data and model real-world entities. It showed how to declare and create named and anonymous structs, access and modify structs fields, and use nested structs to create more complex data structures. Structs are the basis for creating methods and interfaces in GoLang.
Introduction
A struct is a user-defined type that represents a collection of fields. It can be used where it makes sense to group the data into a single unit rather than having each as separate values.
For instance, an employee has a firstName, lastName, and age. Grouping these three properties into a single struct named Employee makes sense. A struct can also contain fields of different types, such as string, int, float64, etc. This concept is generally compared with the classes in object-oriented programming, but structs are simpler and do not support inheritance or methods.
A struct can be declared using the type keyword and the struct keyword, followed by a list of fields inside curly braces. An example of a real-world entity represented as a struct is an address with fields such as name, street, city, state, and Pincode.
Sure, here is a code snippet that shows how to declare and use a struct type Address:
package main
import (
"fmt"
)
func main()
// Declaring a struct type Address
type Address struct
// Creating an Address struct using a struct literal
var addr1 = Address
var addr2 = Address
Syntax
- To declare a named struct type, we use the
type
keyword followed by the name of the type and thestruct
keyword. Inside the curly braces, we list the fields of the struct, each with a name and a type. - The name of the type and the fields should start with a capital letter if we want them to be exported (visible outside the package).
- The name of the type should be descriptive and usually singular. The names of the fields should be concise and clear.
- The type of the fields can be any valid Go type, such as built-in types (string, int, bool, etc.), user-defined types (other structs, interfaces, etc.), or composite types (arrays, slices, maps, etc.).
- For example, to declare a struct type Employee with fields firstName, lastName, age, and salary, we can write:
// Declaring a named struct type Employee
type Employee struct
Named struct
- To create structs of a named type, we can use two different syntaxes:
- one with specifying field names and
- one without specifying field names.
- The first syntax uses a struct literal, a list of field names and values inside curly braces.
- The order of the fields does not matter in this syntax, and we can omit some fields if we want them to have zero values.
- The advantage of this syntax is that it makes the code more readable and clear. The disadvantage is that it can be verbose and repetitive if we have many fields or many structs to create.
- For example, to create an Employee struct using this syntax, we can write:
// Creating an Employee struct using a struct literal
employee1 := Employee
- The second syntax lists values inside curly braces without specifying the field names.
- The order of the values must match the order of the fields in the struct declaration in this syntax, and we cannot omit any field.
- The advantage of this syntax is that it is concise and compact.
- The disadvantage is that it can be confusing and error-prone if we have many fields or change the order of the fields in the struct declaration. For example, to create an Employee struct using this syntax, we can write:
// Creating an Employee struct using a list of values
employee2 := Employee
Anon structs
- We can use an anonymous struct to create structs without declaring a new data type. An anonymous struct is a struct literal without a type name. It can be helpful when we need a temporary data structure not used elsewhere in the code.
- For example, we can use an anonymous struct to store configuration data or pass some arguments to a function.
- The disadvantage of using an anonymous struct is that we cannot reuse or refer to it by name. For example, to create an anonymous struct with fields firstName, lastName, age, and salary, we can write:
// Creating an anonymous struct
employee3 := struct
It also can be written without specifying the field name
employee4 := struct
Assigning fields of a struct
- To access individual fields of a struct, we use the dot (.) operator followed by the field name.
- We can use this operator on both struct variables and struct pointers. We can also modify or assign values to fields using the same operator and the assignment (=) operator.
- For example, to access and modify fields of Employee structs, we can write:
// Accessing fields of a struct
fmt.Println(employee1.FirstName) // prints Soumendra
fmt.Println(employee2.Age) // prints 50
fmt.Println(employee3.Salary) // prints 30000
fmt.Println(employee4.Salary) // prints 70000
// Modifying or assigning values to fields
employee1.Salary = 60000 // modifying field value
employee2.LastName = "Gandhi" // assigning new value to field
fmt.Println(employee1.Salary) // prints 60000
fmt.Println(employee2.LastName) // prints Gandhi
Nested struct
Nested structs are structs that have fields that are themselves structs. This allows us to create more complex data structures representing hierarchical or nested relationships.
For example, we can create a nested struct to represent a person with an address with fields such as street, city, and state. To declare a nested struct, we can either define each struct type separately and use them as field types, or we can define anonymous structs inside others.
To create a nested struct, we can use either syntax for creating named or anonymous structs, but we have to specify the values for each nested field using curly braces. To access or modify fields of a nested struct, we have to use the dot (.) operator multiple times to reach the desired field. For example, to declare and use a nested struct Employee with an Address field, we can write:
package main import "fmt" type Address struct type Employee struct func main()
Conclusion
In this blog post, we have learned about structs in GoLang, which are user-defined types that represent collections of fields. We have seen how to declare and create named, and anonymous structs using different syntaxes, access and modify structs fields using the dot (.) operator, and use nested structs to create more complex data structures. Structs are helpful for grouping data into a single unit and modeling real-world entities. They are also the basis for creating methods and interfaces in GoLang. For further reading on structs in GoLang, you can check out these links: