Objects → Structs
Grouping data and behavior
Introduction
In this lesson, you'll learn about objects → structs in Go. Coming from JavaScript, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In JavaScript, you're familiar with grouping data and behavior.
Go has its own approach to grouping data and behavior, which we'll explore step by step.
The Go Way
Let's see how Go handles this concept. Here's a typical example:
package main
import "fmt"
// Struct (no classes)
type Person struct {
Name string
Age int
}
// Method with receiver
func (p Person) Greet() string {
return "Hi, I'm " + p.Name
}
// Pointer receiver for mutation
func (p *Person) Birthday() { p.Age++ }
p := Person{Name: "Alice", Age: 30}
fmt.Println(p.Greet())
// Copy and update
updated := p
updated.Age = 31Comparing to JavaScript
Here's how you might have written similar code in JavaScript:
// Object literal
const person = { name: "Alice", age: 30 };
// Class
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() { return "Hi, I'm " + this.name; }
}
const p = new Person("Alice", 30);
console.log(p.greet());
// Spread / copy
const updated = { ...person, age: 31 };You may be used to different syntax or behavior.
Go has no classes — structs + methods replace JS classes
You may be used to different syntax or behavior.
Go methods are defined outside the struct with a receiver
You may be used to different syntax or behavior.
Pointer receiver (*T) required for mutation; JS always mutates by default
You may be used to different syntax or behavior.
No class inheritance in Go — use composition (embedding)
Step-by-Step Breakdown
1. Struct vs Class
Go structs define data fields. Methods are separate functions with a receiver parameter — Go's equivalent of class methods.
class Person { constructor(name, age) { this.name=name; } }type Person struct { Name string; Age int }2. Receiver Methods
Go attaches behavior to a type via receiver syntax. Use value receiver (p Person) for reads, pointer receiver (*p Person) for writes.
greet() { return "Hi, " + this.name; }func (p Person) Greet() string { return "Hi, " + p.Name }3. Composition over Inheritance
Go has no inheritance. Instead, embed one struct in another to reuse its fields and methods.
type Employee struct {
Person // embedded — Employee has Name, Age, Greet()
Department string
}Common Mistakes
When coming from JavaScript, developers often make these mistakes:
- Go has no classes — structs + methods replace JS classes
- Go methods are defined outside the struct with a receiver
- Pointer receiver (*T) required for mutation; JS always mutates by default
Key Takeaways
- Go structs replace JS classes
- Methods use receiver syntax: func (p Person) Method()
- Pointer receiver for mutation: func (p *Person) Mutate()
- Composition via embedding replaces inheritance