Structs and Methods in Go

Hey! If you love Go and building Go apps as much as I do, let's connect on Twitter or LinkedIn. I talk about this stuff all the time!

Want to learn how to build better Go applications faster and easier? You can.

Check out my course on the Go Standard Library. You can check it out now for free.


Understanding Structs and Methods in Go

Introduction:

In Go, a struct is a way to create your own custom data types. It’s like building a blueprint for a new type of object.

Think about it this way: you have a collection of information (data) that belongs together. Instead of having separate variables for each piece of information, a struct lets you combine them into a single structure. This is helpful because it keeps your code organized and easy to understand.

Introduction to Structs:

Let’s say you want to store information about a person. You could use separate variables for their name, age, address, etc., but that can get messy. A struct lets you create a new type named “Person” to hold all that data in a structured way:

Step by step explanation:

  1. Define the Struct: We start by creating a structure (blueprint) named “Person” using the type keyword. This structure would typically include fields for things like name, age, and address. For example:
package main

import "fmt"

// Define a struct to represent a person.
type Person struct {
  FirstName string
  LastName string
  Age int
  Address string
}

func main() {
  // Create a new instance of the "Person" struct.
  person1 := Person{
    FirstName: "John",
    LastName: "Doe",
    Age: 30,
    Address: "123 Main Street",
  }

  fmt.Println("First Name:", person1.FirstName)
  fmt.Println("Last Name:", person1.LastName)
  fmt.Println("Person's age:", person1.Age)
}

This code defines a struct named “Person” with three fields: FirstName, LastName, and Address.

Why it matters:

Structs are powerful for organizing data. Instead of thinking about a person as separate pieces of information (like individual variables for firstName, lastName, and age), we can create a single type that defines all the essential characteristics.

Creating Meaningful Data Structures:

In this example, “Person” is a custom data structure. We can think of it like a blueprint for building a person object in Go.

type Person struct {
  FirstName string
  LastName string
  Age int
  // ... other fields

  // Example:
  Name string
  Age int
  Height float64
  Weight float64

}

func (p *Person) speak() {
  fmt.Println("Hello, my name is", p.FirstName, p.LastName)
}

Creating a “Person” Type:

Let’s say you want to use the Person struct to store information about a person and their address.

You can think of it like this:

// Define a struct for a person

type Person struct {
  FirstName string
  LastName string
  Age int
  Height float64
  speak func()
}

func (p *Person) setHeight(height float64) {
  // ... code to change the height of the person
  fmt.Println("Setting a height for this Person!")
  // ... code to access and modify the 'height' field

}

Speaking about the “Person” type:

The speak function is a great example of how Go allows you to define functions that belong to a specific data structure.

In this case, the ‘Person’ struct would have a function defined on it:

// ... (previous code for 'FirstName', 'Age' and 'Height' fields)
  // Define a function to speak.

func (p *Person) sayHello() {
  fmt.Println("Hello,", p.LastName, "!", p.FirstName)
}

This is a good example of what we call a method. A method is simply a function that’s defined on a specific data type.

By defining the speak function directly on the ‘Person’ struct, we can give each person instance its own way of saying “Hello” through the p.speak.

Defining methods:

A method in Go is a function that has a special receiver parameter. This allows us to define functions specific to an object.

In our Person example, the sayHello function would be defined as:

func (p *Person) sayHello() {
  // ... (code for the 'speak' method)
}

type Person struct {
  FirstName string
  LastName string
  Age int
  Height float64

}

// This code defines a new instance of the 'Person' struct. 
// We are defining a function `sayHello` that is specific to the 'Person' type:

func (p *Person) sayHello() {
  fmt.Println("Hello,", p.LastName, "!", p.firstName)
}

func main() {
  // ...
  person := Person{} // We don't need a height in this example!
  person.sayHello() // Call the 'sayHello' function directly on the struct instance
}

Why use Structs and Methods?

  • Organization: Imagine trying to keep track of all the information about a person using separate variables. You’d have a lot of data floating around: firstName, lastName, age, height, weight, address, etc. A struct lets you combine these into a single, organized unit.

  • Readability: Keeping all the information for a person together in a struct makes your code easier to understand and maintain. You can easily see that ‘person1’ has both ‘firstName’, ‘lastName’, age, and ‘height’ as attributes.

  • Reusability: By defining methods on the Person struct, you can reuse the same code for handling a person’s name (or in this case, their height) across different parts of your program.**

Reusability:

Using a method to define the ‘hello’ function is just one way to show how they are useful. Imagine needing to calculate the BMI of a person.

// ... (previous code for "Person" type)

// Function to represent height in the 'Person' struct

func (p *Person) sayHello() {
  fmt.Println("This is a function to print a greeting!") 
}

type Person struct {
  FirstName string
  LastName string
  Height float64
  // ... other fields

  // Define a `sayHello` method on the 'Person' type
  func (p *Person) speak() {
    println("Hello,", p.lastName, "!") 
  }

type Person struct {
  FirstName string
  LastName string
  Age int
  Age float64 // We can use 'float64' for height and age

  // ... (rest of the code)

  // Calculate BMI
  func (p *Person) speak() {
    fmt.Println("Hello, I'm a", p.FirstName, "and I'm", personAge, "years old.")
  }

BMI Calculation:

In this example, we can use the calculateBMI function for calculating the BMI of any object that has a height and weight value:

  • Person:
// ... (previous code)
  
  person := Person{FirstName: "John", LastName: "Doe", Height: 1.75, Weight: 75.0} // Example of 'Person' struct with fields



Stay up to date on the latest in Coding for AI and Data Science

Intuit Mailchimp