Structs
Analogically speaking, if you have programmed in other Object-oriented supported languages, you may be familiar with classes. the general definition of a class will be that it’s a blueprint or template from which objects can be created. Like classes in Java or other Object Oriented programming languages, Struct is a composite data type blueprint that allows you to group different types into a single unit. They are very similar to classes but they don’t have the methods as classes will have. Struct provides a way of creating complex data structures from custom types
How to Create a Struct
To create a struct, we use the type keyword followed by the name of the struct and then, subsequently, the fields it will contain.
type Person struct {
Name string
Age int
Height float64
}
Now we need to instantiate an object of the type Person we defined above.
person := Person{
Name: "John Doe",
Age: 30,
Height: 5.8,
}
with the above, we can now access or modify the fields on the person above.
package main
import "fmt"
func main() {
type Person struct {
Name string
Age int
Height float64
}
person := Person{
Name: "John Doe",
Age: 30,
Height: 5.8,
}
//Accessing struct fields
fmt.Println(person.Name) // Outputs: John Doe
fmt.Println(person.Age) // Output: 30
fmt.Println(person.Height) // Output: 5.8
// Updateing struct fields
person.Name = "Harisu Fanyui"
person.Age = 28
fmt.Println("Updated Name: ", person.Name) // Outputs: Updated Name: Harisu Fanyui
fmt.Println("Updated Age: ", person.Age) // Outputs: Updated Age: 28
}
It is important to note that structs can also have methods. These can come in two forms.
- Pointer Receiver
- Value receiver.
Consider using a value receiver only when no mutation is happening on the struct. ie say just some computation needed to generate some result of the struct. eg let’s write a function that returns the string version of an object. Just like we have the toString method in other object-oriented programming languages. here we can have it written as follows
func (p Person) String() string {
return p.Name + " is " + strconv.Itoa(int(p.Age)) + " years old and " + strconv.FormatFloat(p.Height, 'E', -1, 32) + " feet tall"
}
however, for the pointer receiver, you want to use it for two reasons.
- When there is a mutation happening in the method on the receiver object.
- To avoid copying data on each method call.
Excercise
- Write a function that takes a struct representing a Rectangle (with fields for length and width) as input and calculates its area.
- Create a struct to represent a Book, with fields for title, author, and price. Write a function that takes a slice of Book and returns the total price of all the books.
More in Miscellanous