Encoding dan Decoding
Go menyediakan berbagai package untuk encoding dan decoding data dalam format yang berbeda seperti JSON, XML, dan binary.
Contoh Masalah
Bagaimana cara:
- Mengubah struct ke JSON dan sebaliknya
- Bekerja dengan XML
- Menggunakan encoding binary
- Custom marshaling
Penyelesaian
package main
import (
"encoding/json"
"encoding/xml"
"encoding/gob"
"fmt"
"os"
"time"
)
// 1. Basic struct untuk JSON
type Person struct {
Name string `json:"name" xml:"name"`
Age int `json:"age" xml:"age"`
Address string `json:"address,omitempty" xml:"address,omitempty"`
BirthDate time.Time `json:"birth_date" xml:"birth_date"`
Private string `json:"-" xml:"-"` // Akan dilewati
}
// 2. Nested struct untuk XML
type Company struct {
XMLName xml.Name `xml:"company"`
Name string `xml:"name,attr"`
Address string `xml:"address"`
People []Person `xml:"people>person"`
}
// 3. Custom marshaling
type Duration struct {
time.Duration
}
func (d Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}
func (d *Duration) UnmarshalJSON(b []byte) error {
var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return err
}
switch value := v.(type) {
case float64:
d.Duration = time.Duration(value)
case string:
var err error
d.Duration, err = time.ParseDuration(value)
if err != nil {
return err
}
default:
return fmt.Errorf("invalid duration")
}
return nil
}
// 4. Struct untuk binary encoding
type Message struct {
ID int
Content string
Time time.Time
}
func main() {
// Contoh 1: JSON Encoding/Decoding
fmt.Println("JSON Example:")
person := Person{
Name: "John Doe",
Age: 30,
Address: "Jakarta",
BirthDate: time.Date(1993, 1, 1, 0, 0, 0, 0, time.UTC),
Private: "rahasia",
}
// Marshal ke JSON
jsonData, err := json.MarshalIndent(person, "", " ")
if err != nil {
fmt.Printf("Error marshaling JSON: %v\n", err)
return
}
fmt.Printf("JSON:\n%s\n", string(jsonData))
// Unmarshal dari JSON
var decodedPerson Person
err = json.Unmarshal(jsonData, &decodedPerson)
if err != nil {
fmt.Printf("Error unmarshaling JSON: %v\n", err)
return
}
fmt.Printf("Decoded: %+v\n", decodedPerson)
// Contoh 2: XML Encoding/Decoding
fmt.Printf("\nXML Example:\n")
company := Company{
Name: "Tech Corp",
Address: "Silicon Valley",
People: []Person{
person,
{
Name: "Jane Smith",
Age: 28,
BirthDate: time.Date(1995, 1, 1, 0, 0, 0, 0, time.UTC),
},
},
}
// Marshal ke XML
xmlData, err := xml.MarshalIndent(company, "", " ")
if err != nil {
fmt.Printf("Error marshaling XML: %v\n", err)
return
}
fmt.Printf("XML:\n%s\n", string(xmlData))
// Unmarshal dari XML
var decodedCompany Company
err = xml.Unmarshal(xmlData, &decodedCompany)
if err != nil {
fmt.Printf("Error unmarshaling XML: %v\n", err)
return
}
fmt.Printf("Decoded company name: %s\n", decodedCompany.Name)
// Contoh 3: Custom Marshaling
fmt.Printf("\nCustom Marshaling Example:\n")
type Task struct {
Name string `json:"name"`
Duration Duration `json:"duration"`
}
task := Task{
Name: "Long Task",
Duration: Duration{time.Hour * 2},
}
// Marshal ke JSON
taskJSON, err := json.MarshalIndent(task, "", " ")
if err != nil {
fmt.Printf("Error marshaling task: %v\n", err)
return
}
fmt.Printf("Task JSON:\n%s\n", string(taskJSON))
// Unmarshal dari JSON
var decodedTask Task
err = json.Unmarshal(taskJSON, &decodedTask)
if err != nil {
fmt.Printf("Error unmarshaling task: %v\n", err)
return
}
fmt.Printf("Decoded task duration: %v\n", decodedTask.Duration.Duration)
// Contoh 4: Binary Encoding (gob)
fmt.Printf("\nBinary Encoding Example:\n")
msg := Message{
ID: 1,
Content: "Hello, World!",
Time: time.Now(),
}
// Encode ke file
file, err := os.Create("message.gob")
if err != nil {
fmt.Printf("Error creating file: %v\n", err)
return
}
encoder := gob.NewEncoder(file)
err = encoder.Encode(msg)
file.Close()
if err != nil {
fmt.Printf("Error encoding: %v\n", err)
return
}
// Decode dari file
file, err = os.Open("message.gob")
if err != nil {
fmt.Printf("Error opening file: %v\n", err)
return
}
var decodedMsg Message
decoder := gob.NewDecoder(file)
err = decoder.Decode(&decodedMsg)
file.Close()
if err != nil {
fmt.Printf("Error decoding: %v\n", err)
return
}
fmt.Printf("Decoded message: %+v\n", decodedMsg)
// Cleanup
os.Remove("message.gob")
}
Penjelasan Kode
JSON
- Marshal/Unmarshal
- Struct tags
- Pretty printing
XML
- XML tags
- Nested structures
- Attributes
Binary
- Gob encoding
- File I/O
- Custom types
Output
JSON Example:
JSON:
{
"name": "John Doe",
"age": 30,
"address": "Jakarta",
"birth_date": "1993-01-01T00:00:00Z"
}
Decoded: {Name:John Doe Age:30 Address:Jakarta BirthDate:1993-01-01 00:00:00 +0000 UTC Private:}
XML Example:
XML:
<company name="Tech Corp">
<address>Silicon Valley</address>
<people>
<person>
<name>John Doe</name>
<age>30</age>
<address>Jakarta</address>
<birth_date>1993-01-01T00:00:00Z</birth_date>
</person>
<person>
<name>Jane Smith</name>
<age>28</age>
<birth_date>1995-01-01T00:00:00Z</birth_date>
</person>
</people>
</company>
Decoded company name: Tech Corp
Custom Marshaling Example:
Task JSON:
{
"name": "Long Task",
"duration": "2h0m0s"
}
Decoded task duration: 2h0m0s
Binary Encoding Example:
Decoded message: {ID:1 Content:Hello, World! Time:2024-01-21 11:57:22.123456789 +0700 WIB}
Tips
- Gunakan struct tags
- Handle error dengan baik
- Validasi input
- Perhatikan performa
- Pilih format yang sesuai kebutuhan