Ce face encoding/json.Decoder.More
dec.More() returnează true dacă în lista (sau obiectul) care se citește acum mai există un element. Împreună cu dec.Token(), care citește un singur simbol ([, ], {, o cheie…), permite parcurgerea unei liste JSON uriașe element cu element: citești [ cu Token, apoi for dec.More() { dec.Decode(&element) }, apoi ].
Așa nu ții toată lista în memorie: un fișier de 2 GB cu milioane de comenzi se procesează cu memorie constantă. La nivelul de sus (în afara unei liste), More spune dacă mai urmează date în flux, util ca să verifici că un corp nu are nimic după obiectul așteptat.
Ce returnează
More: bool. Token: simbolul citit (json.Delim, string, float64, bool, nil) și o eroare.
Exemple
Exemplul 1: O listă mare citită element cu element
package main
import (
"encoding/json"
"fmt"
"strings"
)
type Comanda struct {
ID int `json:"id"`
Total float64 `json:"total"`
}
func main() {
date := `[
{"id": 1, "total": 120.5},
{"id": 2, "total": 89},
{"id": 3, "total": 310.25}
]`
dec := json.NewDecoder(strings.NewReader(date))
inceput, err := dec.Token() // [
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Început:", inceput)
suma := 0.0
for dec.More() {
var c Comanda
if err := dec.Decode(&c); err != nil {
fmt.Println(err)
return
}
fmt.Printf("comanda %d: %.2f lei\n", c.ID, c.Total)
suma += c.Total
}
sfarsit, _ := dec.Token() // ]
fmt.Println("Sfârșit:", sfarsit)
fmt.Printf("Total: %.2f lei\n", suma)
}
Rezultat
Început: [
comanda 1: 120.50 lei
comanda 2: 89.00 lei
comanda 3: 310.25 lei
Sfârșit: ]
Total: 519.75 lei
Exemplul 2: Date în plus după obiect
După Decode, More() spune dacă în corp a mai rămas ceva.
package main
import (
"encoding/json"
"fmt"
"strings"
)
func unSingurObiect(text string) error {
dec := json.NewDecoder(strings.NewReader(text))
var v map[string]any
if err := dec.Decode(&v); err != nil {
return err
}
if dec.More() {
return fmt.Errorf("date în plus după obiectul JSON")
}
return nil
}
func main() {
fmt.Println(unSingurObiect(`{"a": 1}`))
fmt.Println(unSingurObiect(`{"a": 1} `))
fmt.Println(unSingurObiect(`{"a": 1} {"b": 2}`))
}
Rezultat
<nil>
<nil>
date în plus după obiectul JSON
Greșeli frecvente
- Faci
for dec.More()pe o listă fără să citești întâi[cuToken():Decodeîncearcă să citească toată lista într-un singur element și dă eroare de tip.
Comenzi înrudite
encoding/json.NewDecoder: Creează un Decoder care citește JSON dintr-un io.Reader (corpul unei cereri, un fișier); Decode citește o valoare.encoding/json.Decoder.DisallowUnknownFields: Face ca Decode să returneze eroare când JSON-ul are chei care nu există în structura țintă.encoding/json.RawMessage: Un fragment JSON păstrat ca text brut: decodarea lui se amână (ex. după un câmp „tip”) sau se trimite mai departe neschimbat.