Ce face encoding/json.RawMessage
Un câmp de tip json.RawMessage nu este decodat de Unmarshal: primește textul JSON exact al valorii, ca []byte. La Marshal, textul este pus în rezultat așa cum este.
Cazul tipic: mesaje cu formă variabilă, de exemplu {"tip": "plata", "date": {...}}, unde forma lui date depinde de tip. Citești întâi învelișul cu Date json.RawMessage, te uiți la Tip, apoi faci un al doilea Unmarshal pe Date în structura potrivită. Este util și când doar transmiți mai departe un fragment pe care nu trebuie să-l înțelegi.
Ce returnează
Este un tip; se folosește pentru câmpuri și variabile.
Exemple
Exemplul 1: Mesaje cu tipuri diferite
package main
import (
"encoding/json"
"fmt"
)
type Mesaj struct {
Tip string `json:"tip"`
Date json.RawMessage `json:"date"`
}
type Plata struct {
Suma float64 `json:"suma"`
Moneda string `json:"moneda"`
}
type Livrare struct {
Curier string `json:"curier"`
AWB string `json:"awb"`
}
func main() {
flux := []string{
`{"tip":"plata","date":{"suma":249.9,"moneda":"RON"}}`,
`{"tip":"livrare","date":{"curier":"FAN","awb":"2026101900123"}}`,
}
for _, text := range flux {
var m Mesaj
if err := json.Unmarshal([]byte(text), &m); err != nil {
fmt.Println(err)
continue
}
fmt.Printf("tip=%s, date brute=%s\n", m.Tip, m.Date)
switch m.Tip {
case "plata":
var p Plata
json.Unmarshal(m.Date, &p)
fmt.Printf(" plată de %.2f %s\n", p.Suma, p.Moneda)
case "livrare":
var l Livrare
json.Unmarshal(m.Date, &l)
fmt.Printf(" colet %s prin %s\n", l.AWB, l.Curier)
}
}
}
Rezultat
tip=plata, date brute={"suma":249.9,"moneda":"RON"}
plată de 249.90 RON
tip=livrare, date brute={"curier":"FAN","awb":"2026101900123"}
colet 2026101900123 prin FAN
Exemplul 2: Fragment trimis mai departe neschimbat
package main
import (
"encoding/json"
"fmt"
)
type Raspuns struct {
Status string `json:"status"`
Sursa string `json:"sursa"`
Date json.RawMessage `json:"date"`
}
func main() {
deLaFurnizor := json.RawMessage(`{"temp": 14.5, "umiditate": 71, "alerte": []}`)
r := Raspuns{Status: "ok", Sursa: "meteo-extern", Date: deLaFurnizor}
out, _ := json.Marshal(r)
fmt.Println(string(out))
}
Rezultat
{"status":"ok","sursa":"meteo-extern","date":{"temp":14.5,"umiditate":71,"alerte":[]}}
Greșeli frecvente
- Pui într-un
RawMessagetext care nu este JSON valid și apoi faciMarshal: rezultă eroare. Verifică cujson.Validdacă textul vine din altă parte.
Comenzi înrudite
encoding/json.Unmarshal: Citește JSON și completează o valoare Go (structură, map, slice) dată prin pointer; potrivește cheile după etichetele json.encoding/json.Marshal: Transformă o valoare Go (structură, map, slice) în JSON compact; etichetele json:”…” aleg numele și regulile câmpurilor.encoding/json.Marshaler: Interfețe pentru a controla singur forma JSON a unui tip: MarshalJSON la scriere, UnmarshalJSON la citire.