📦 Go Files: Packing and Unpacking Your Data Boxes
Imagine you have a toy box. Sometimes you want to neatly organize your toys into labeled compartments (that’s marshaling). Other times, you open a box someone gave you and figure out what’s inside (that’s unmarshaling). In Go, we do the same thing with data!
🎯 What You’ll Learn
We’re going to explore how Go talks to the world using two popular formats:
- JSON – Like sending a letter with clearly labeled sections
- CSV – Like a simple spreadsheet with rows and columns
Think of it like this: Your Go program is your house. JSON and CSV are the languages you use to send and receive packages from friends around the world.
📤 JSON Marshaling: Packing Your Toy Box
What is it? Turning your Go data into a JSON string that others can read.
Real-life example: You have a toy car with a color and speed. You want to tell your friend about it in a way they understand.
package main
import (
"encoding/json"
"fmt"
)
type Car struct {
Color string
Speed int
}
func main() {
myCar := Car{Color: "red", Speed: 100}
// Pack the car info into JSON
packed, _ := json.Marshal(myCar)
fmt.Println(string(packed))
}
Output:
{"Color":"red","Speed":100}
🎉 You just packed your toy car into a box (JSON) that anyone can open!
Pretty Packing
Want it to look nicer? Use MarshalIndent:
pretty, _ := json.MarshalIndent(myCar, "", " ")
fmt.Println(string(pretty))
Output:
{
"Color": "red",
"Speed": 100
}
📥 JSON Unmarshaling: Opening Someone’s Gift Box
What is it? Taking a JSON string and turning it back into Go data you can use.
Real-life example: Your friend sends you a description of their pet. You want to understand it in your own language.
package main
import (
"encoding/json"
"fmt"
)
type Pet struct {
Name string
Age int
}
func main() {
// This is the box from your friend
jsonData := `{"Name":"Buddy","Age":3}`
// Create an empty pet to fill
var myPet Pet
// Unpack the JSON into our pet
json.Unmarshal([]byte(jsonData), &myPet)
fmt.Println("Pet name:", myPet.Name)
fmt.Println("Pet age:", myPet.Age)
}
Output:
Pet name: Buddy
Pet age: 3
⚠️ Important: Notice the & before myPet? That’s like saying “put the stuff HERE in this exact spot!”
🏷️ JSON Struct Tags: Custom Labels on Your Box
What is it? Special instructions that tell Go how to name things in JSON.
Why do we need it? In Go, we use CapitalLetters. But JSON from websites often uses lowercase or snake_case.
package main
import (
"encoding/json"
"fmt"
)
type User struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Age int `json:"age"`
Secret string `json:"-"`
}
func main() {
user := User{
FirstName: "Alice",
LastName: "Wonder",
Age: 10,
Secret: "hidden",
}
data, _ := json.MarshalIndent(user, "", " ")
fmt.Println(string(data))
}
Output:
{
"first_name": "Alice",
"last_name": "Wonder",
"age": 10
}
Tag Magic Explained
| Tag | What It Does |
|---|---|
json:"name" |
Use “name” in JSON instead |
json:"-" |
Hide this field completely |
json:",omitempty" |
Skip if the value is empty |
type Item struct {
Name string `json:"name"`
Price int `json:"price,omitempty"`
}
If Price is 0, it won’t show up in the JSON!
📊 CSV: The Simple Spreadsheet
CSV stands for Comma Separated Values. It’s like a basic spreadsheet where commas separate each column.
name,age,city
Alice,10,Paris
Bob,12,London
Think of each line as a row in your spreadsheet, and commas as the walls between columns.
📖 Reading CSV: Opening the Spreadsheet
package main
import (
"encoding/csv"
"fmt"
"strings"
)
func main() {
data := `name,age,city
Alice,10,Paris
Bob,12,London`
reader := csv.NewReader(strings.NewReader(data))
// Read all rows at once
records, _ := reader.ReadAll()
for i, row := range records {
fmt.Printf("Row %d: %v\n", i, row)
}
}
Output:
Row 0: [name age city]
Row 1: [Alice 10 Paris]
Row 2: [Bob 12 London]
Reading Row by Row
For big files, read one row at a time:
reader := csv.NewReader(strings.NewReader(data))
for {
row, err := reader.Read()
if err != nil {
break // End of file
}
fmt.Println(row)
}
✍️ Writing CSV: Creating Your Own Spreadsheet
package main
import (
"encoding/csv"
"os"
)
func main() {
file, _ := os.Create("friends.csv")
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()
// Write header
writer.Write([]string{"Name", "Age", "Hobby"})
// Write data rows
writer.Write([]string{"Emma", "9", "Drawing"})
writer.Write([]string{"Liam", "11", "Soccer"})
}
This creates a file called friends.csv:
Name,Age,Hobby
Emma,9,Drawing
Liam,11,Soccer
Writing Multiple Rows at Once
data := [][]string{
{"Name", "Score"},
{"Alice", "95"},
{"Bob", "87"},
}
writer.WriteAll(data)
🔄 The Complete Picture
graph TD A["Go Struct"] -->|Marshal| B["JSON String"] B -->|Unmarshal| A C["Go Slices"] -->|Write| D["CSV File"] D -->|Read| C
🎮 Quick Reference
| Task | Function | Package |
|---|---|---|
| Go → JSON | json.Marshal() |
encoding/json |
| JSON → Go | json.Unmarshal() |
encoding/json |
| Pretty JSON | json.MarshalIndent() |
encoding/json |
| Read CSV | csv.NewReader().Read() |
encoding/csv |
| Write CSV | csv.NewWriter().Write() |
encoding/csv |
💡 Remember This!
- Marshaling = Packing (Go → JSON/CSV)
- Unmarshaling = Unpacking (JSON → Go)
- Struct Tags = Custom labels for your JSON fields
- CSV = Simple rows and columns separated by commas
🚀 You Did It!
Now you know how to:
- ✅ Turn Go data into JSON
- ✅ Read JSON back into Go
- ✅ Use tags to customize JSON names
- ✅ Read and write CSV files
You’re ready to send and receive data packages with the whole world! 🌍
