Beyond Strings and Integers
So far, we've worked with Go's built-in data types like string
, int
, and bool
. These are great, but what if you want to represent something more complex, like a user, a product, or a car? A user isn't just a string; they have a name, an email, an age, and so on.
To handle this, Go allows us to define our own custom data types using Structs. We can then attach functions to these structs, which are called Methods.
1. What is a Struct? (The Blueprint)
A struct (short for structure) is a collection of fields that defines a new data type. It's like creating a blueprint for your data.
Analogy: A blank biodata form. The form has predefined fields like "Name," "Address," and "Age," but it doesn't contain any actual information yet. It's just the template.
Defining a Struct
We use the type
and struct
keywords to define a new struct. Let's create one for a User
.
package main
import "fmt"
// This is our blueprint for a User.
// The fields (Name, Email, Age) start with a capital letter
// to make them public (we'll cover this later).
type User struct {
Name string
Email string
Age int
}
func main() {
// We'll create a user here in the next step
}
2. Creating Data from a Struct (The Instance)
Once we have the blueprint, we can create actual data from it. An individual piece of data created from a struct is called an instance or an object.
We create an instance and access its fields using the dot .
notation.
// (Continuing from the code above)
func main() {
// Creating an instance of our User struct
user1 := User{
Name: "Budi",
Email: "budi@email.com",
Age: 30,
}
// Creating another instance
user2 := User{
Name: "Siti",
Email: "siti@email.com",
Age: 25,
}
// Accessing the fields
fmt.Println("User 1's Name:", user1.Name)
fmt.Println("User 2's Email:", user2.Email)
}
This is far more organized than managing three separate variables (userName
, userEmail
, userAge
) for each user!
3. Methods: Giving Your Structs Behavior
Now that we have a blueprint for our data (struct
), we can define actions or behaviors that this data can perform. In Go, a function that is attached to a specific struct is called a Method.
Analogy: If a Car
struct holds data like Color
and Speed
, its methods would be actions like StartEngine()
or Accelerate()
.
Defining and Using a Method
A method is defined almost exactly like a function, but with one special addition: the receiver. The receiver is what links the function to the struct.
package main
import "fmt"
type User struct {
Name string
Email string
Age int
}
// This is a METHOD because it has a receiver: '(u User)'
// The receiver links this function to the User struct.
// Inside this method, 'u' refers to the specific instance of the user.
func (u User) greet() {
fmt.Printf("Hello, my name is %s and I am %d years old.\n", u.Name, u.Age)
}
func main() {
// Creating an instance of our User struct
user1 := User{
Name: "Budi",
Email: "budi@email.com",
Age: 30,
}
// We call the method using the dot notation from the instance
user1.greet() // Prints: Hello, my name is Budi and I am 30 years old.
}
How it works:
- We defined the
greet()
method with a receiver(u User)
. This tells Go thatgreet()
belongs to theUser
struct. - Inside the method, we can access the fields of that specific user instance through the receiver variable (
u
). - We call the method from the instance variable (
user1.greet()
).
Putting It All Together: A Full Example
Let's combine everything into one complete, runnable program.
package main
import "fmt"
// The blueprint for our data
type User struct {
Name string
Email string
Age int
}
// The behavior attached to the User struct
func (u User) greet() {
fmt.Printf("Hello, my name is %s and I am %d years old.\n", u.Name, u.Age)
}
func main() {
// Create two instances of User
user1 := User{
Name: "Budi",
Email: "budi@email.com",
Age: 30,
}
user2 := User{
Name: "Siti",
Email: "siti@email.com",
Age: 25,
}
// Call the method from each instance
user1.greet()
user2.greet()
}
Conclusion
You've just taken a massive leap in writing organized Go code! You now know how to:
- Group related data together into a clean blueprint using Structs.
- Attach specific behaviors to that data using Methods.
This pattern is fundamental to building larger, more complex applications. It allows you to create self-contained components that are easy to understand and reuse.
In the next part, we'll dive into one of Go's most powerful (and sometimes tricky) concepts: Pointers. We'll learn how they allow us to modify our structs and write more efficient code. See you there!
Top comments (0)