json.Decoder.More
Метод json.Decoder.More возвращает true,
если после текущей позиции в входном потоке есть еще
JSON-токены для чтения, и false - в противном случае.
Этот метод часто используется вместе с json.Decoder.Token
для итеративного разбора JSON-массивов или потоков данных.
Синтаксис
dec.More() bool
Пример с массивом JSON
Давайте разберем JSON-массив и проверим наличие следующих элементов:
package main
import (
"encoding/json"
"fmt"
"strings"
)
func main() {
data := `["a", "b", "c", "d", "e"]`
dec := json.NewDecoder(strings.NewReader(data))
t, err := dec.Token()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Token: %v\n", t)
for dec.More() {
var value string
err := dec.Decode(&value)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Value:", value)
}
t, err = dec.Token()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Token: %v\n", t)
}
Результат выполнения кода:
"Token: ["
"Value: a"
"Value: b"
"Value: c"
"Value: d"
"Value: e"
"Token: ]"
В этом примере мы сначала читаем открывающую скобку массива,
затем в цикле читаем все элементы, пока dec.More
возвращает true, и наконец читаем закрывающую скобку.
Пример с потоком JSON-объектов
Рассмотрим случай, когда входной поток содержит несколько JSON-объектов, следующих друг за другом:
package main
import (
"encoding/json"
"fmt"
"strings"
)
func main() {
data := `{"x": 1}{"y": 2}{"z": 3}`
dec := json.NewDecoder(strings.NewReader(data))
for dec.More() {
var obj map[string]int
err := dec.Decode(&obj)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Object: %v\n", obj)
}
}
Результат выполнения кода:
"Object: map[x:1]"
"Object: map[y:2]"
"Object: map[z:3]"
Здесь dec.More используется для проверки наличия
следующего объекта в потоке, что позволяет читать несколько
корневых JSON-элементов последовательно.
Пример с вложенными структурами
Покажем, как dec.More работает при разборе
вложенных JSON-объектов:
package main
import (
"encoding/json"
"fmt"
"strings"
)
func main() {
data := `{"person": {"name": "John", "age": 30}, "active": true}`
dec := json.NewDecoder(strings.NewReader(data))
t, err := dec.Token()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("First token: %v\n", t)
for dec.More() {
key, err := dec.Token()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Key: %v\n", key)
if key == "person" {
t, err := dec.Token()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Start object: %v\n", t)
for dec.More() {
subKey, err := dec.Token()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf(" SubKey: %v\n", subKey)
var value interface{}
err = dec.Decode(&value)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf(" Value: %v\n", value)
}
t, err = dec.Token()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("End object: %v\n", t)
} else {
var value bool
err := dec.Decode(&value)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Value: %v\n", value)
}
}
t, err = dec.Token()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Last token: %v\n", t)
}
Результат выполнения кода:
"First token: {"
"Key: person"
"Start object: {"
" SubKey: name"
" Value: John"
" SubKey: age"
" Value: 30"
"End object: }"
"Key: active"
"Value: true"
"Last token: }"
Смотрите также
-
метод
json.Decoder.Decode,
который читает следующий JSON-токен и сохраняет его в переданную переменную -
метод
json.Decoder.Token,
который читает следующий JSON-токен и возвращает его -
метод
json.Encoder.Encode,
который кодирует значение в JSON и записывает его в поток -
функцию
json.Valid,
которая проверяет, является ли байтовый массив валидным JSON