Skip to Content
Course content
Click on the "Edit" button in the top corner of the screen to edit your slide content.

I was working on a small project recently—a simple coffee shop ordering system—and I hit a wall that I think perfectly illustrates why we need structs. Initially, I thought I could just get by with basic variables. I mean, what's a coffee order? It's just a size, a roast, and maybe some milk.

The variable mess

I started off like this. I just declared a few variables to hold the details of a single order:

var orderSize = "Large"
var orderRoast = "Dark"
var orderMilk = "Oat"
var orderPrice = 4.50

That works fine for one coffee. But the moment I wanted to handle a second order, things got ugly. I found myself creating order2Size, order2Roast, and so on. I realized that if I wanted to pass this order to a function—say, a function that prints a receipt—I'd have to pass four different arguments every single time. It's tedious and, frankly, a great way to accidentally swap the roast and the milk in a function call.

Grouping the chaos

I need a way to tell Go, "These four pieces of data belong together as a single entity." I can't use an array because arrays require every element to be the same type, and I've got strings and floats mixed here. This is where I introduce a struct.

I'll define a custom type that acts as a blueprint for my order:

type CoffeeOrder struct {
    Size  string
    Roast string
    Milk  string
    Price float64
}

Now, instead of four loose variables, I have one CoffeeOrder. Let's see how I actually create one of these in the code:

func main() {
    // I can initialize it by naming the fields
    myOrder := CoffeeOrder{
        Size:  "Large",
        Roast: "Dark",
        Milk:  "Oat",
        Price: 4.50,
    }
    
    fmt.Println(myOrder)
}

When I run this, Go prints something like {Large Dark Oat 4.5}. It's not the prettiest output, but the data is bundled. I've essentially created my own complex data type.

Getting the data back out

Now that the data is bundled, I need to be able to use it. I can't just treat the myOrder variable as a string or a float; it's a CoffeeOrder. To get to the specific details, I use the dot operator. It's like saying, "Go inside this order and grab the Price."

fmt.Printf("Your %s %s roast is ready! That will be $%.2f", 
    myOrder.Size, 
    myOrder.Roast, 
    myOrder.Price)

This is much cleaner. If I decide later that I need to add a SugarLevel field to my order, I only have to update the struct definition and the places where I create the order. I don't have to hunt down every function signature in my app to add another string argument.

The "Zero Value" surprise

Here's something I noticed while playing around. What happens if I don't provide all the fields when I create the struct?

quickOrder := CoffeeOrder{Size: "Small"}
fmt.Println(quickOrder.Roast)

I expected maybe an error or a null, but Go just printed an empty string. This is because structs follow the same "zero value" rule as basic variables. If I don't specify a value for Roast, it defaults to the zero value for a string (""). For Price, it would be 0.0. It's handy, but it's something to watch out for—you don't want to accidentally charge a customer $0.00 just because you forgot to set the price field.




📋 Practical Task

Build a Server Health Monitor

You are building a tool to monitor the health of various servers in a data center. Instead of tracking server details in separate lists, you need to use a struct to keep the data organized.

Your Task:

  • Define a struct named ServerStatus.
  • Give it the following fields: Hostname (string), IPAddress (string), CPUUsage (float64), and IsOnline (bool).
  • In your main function, create two different instances of ServerStatus (e.g., one for a "Web-Server" and one for a "DB-Server").
  • Print a sentence for each server using its fields, for example: "Server Web-Server (192.168.1.1) is Online with 12.5% CPU usage."
Rating
0 0

There are no comments for now.

to be the first to leave a comment.