Understanding Structs in Go (Part 1): The Foundation of Data Modeling

Written By
Aditya Rawas
Published
in an hour
Go structsGolang structs tutorialstruct in GoGo struct examplestruct methods in GoGo constructor functionGo pointers and structshow to use structs in GoGo beginner tutorialdata modeling in GoGo struct best practicesGo struct initializationGo struct validationGolang object orientedGo struct vs class
Understanding Strcuts in go

In Go, you don’t have classes like you do in Java or Python. Instead, Go provides something more lightweight but equally powerful—structs. Structs let you define your own types that group together related data. If you're building real-world applications, you'll use structs a lot.

Let’s walk through what structs are, how to use them, and how they help in organizing data cleanly.


Why Use Structs?

Imagine you’re building a blogging platform. You want to represent a blog post. Without structs, you’d end up managing individual variables like this:

title := "Go Structs Guide"
author := "Aditya"
content := "This blog explains structs in Go"

What happens when you want to manage 100 blog posts? This quickly becomes a mess. This is where structs help.

They let you define your own blueprint for what a blog post looks like:

type BlogPost struct {
    Title   string
    Author  string
    Content string
}

Now you can work with BlogPost as a whole unit.


How to Create a Struct Instance

Once you’ve defined your struct, you can create a new blog post like this:

post := BlogPost{
    Title:   "Go Structs Guide",
    Author:  "Aditya",
    Content: "This blog explains structs in Go",
}

You can access individual fields like so:

fmt.Println(post.Title)  // Outputs: Go Structs Guide

Go also allows positional initialization (but not preferred when you have many fields):

post := BlogPost{"Short Title", "Author Name", "Content here"}

The downside is: it’s easy to mess up the order of values.


Default Values and Zero Initialization

If you define a struct without assigning values, all fields are automatically initialized to their zero values.

var draft BlogPost
fmt.Println(draft) // Fields will be empty strings: {"" "" ""}

This is useful when you’re preparing an object before filling it in later.


Passing Structs to Functions

You can pass structs to functions just like any other variable:

func PrintPost(post BlogPost) {
    fmt.Println("Title:", post.Title)
}

PrintPost(post)

This creates a copy of the struct. That means changes made inside the function don’t affect the original.


Working with Pointers to Modify Structs

If you want to modify a struct inside a function, you must pass a pointer:

func UpdateAuthor(post *BlogPost, newAuthor string) {
    post.Author = newAuthor
}

UpdateAuthor(&post, "New Author")

Now post.Author will reflect the change.


Methods on Structs

Go lets you attach functions to struct types—these are called methods:

func (p BlogPost) Summary() string {
    return p.Title + " by " + p.Author
}

You call them like this:

fmt.Println(post.Summary())

Note: This method doesn’t modify the struct. It uses a value receiver.


Methods That Modify the Struct

To change values in a method, use a pointer receiver:

func (p *BlogPost) UpdateContent(newContent string) {
    p.Content = newContent
}

Now:

post.UpdateContent("Updated blog post content")

Will actually change the post.Content.


Creating Constructor Functions

Go doesn’t have traditional constructors like some languages, but you can create your own factory functions to initialize structs:

func NewBlogPost(title, author, content string) BlogPost {
    return BlogPost{Title: title, Author: author, Content: content}
}

Now you can use:

post := NewBlogPost("Hello", "Aditya", "Content")

This approach helps reduce boilerplate, especially when the struct has many fields or default logic.


Adding Validation in Constructor Functions

What if you want to prevent empty titles?

func NewBlogPost(title, author, content string) (BlogPost, error) {
    if title == "" {
        return BlogPost{}, fmt.Errorf("title cannot be empty")
    }
    return BlogPost{Title: title, Author: author, Content: content}, nil
}

This ensures you never end up with invalid data.


Coming Up in Part 2

In Part 2 - posting soon, we’ll dive deeper into: