Тип json.Number

Тип json.Number представляет собой строку, содержащую числовое значение в формате JSON. Он используется для декодирования числовых полей без потери точности, так как стандартные типы float64 или int64 могут не сохранить исходное значение. В первый параметр мы передаем строку JSON для декодирования, во второй параметр мы передаем указатель на переменную типа json.Number.

Синтаксис

govar num json.Number
err := json.Unmarshal(data, &num)

Пример

Давайте декодируем число из JSON в тип json.Number и выведем его значение:

gopackage main

import (
  "encoding/json"
  "fmt"
)

func main() {
  data := []byte(`12345678901234567890`)
  var num json.Number
  err := json.Unmarshal(data, &num)
  if err != nil {
    fmt.Println(err)
    return
  }
  res := num.String()
  fmt.Println(res)
}

Результат выполнения кода:

go"12345678901234567890"

Пример

Давайте декодируем объект JSON с числовым полем в структуру с полем типа json.Number:

gopackage main

import (
  "encoding/json"
  "fmt"
)

type User struct {
  ID   json.Number `json:"id"`
  Name string    `json:"name"`
}

func main() {
  data := []byte(`{"id": 98765432109876543210, "name": "Alice"}`)
  var user User
  err := json.Unmarshal(data, &user)
  if err != nil {
    fmt.Println(err)
    return
  }
  res := user.ID.String()
  fmt.Println(res)
}

Результат выполнения кода:

go"98765432109876543210"

Пример

Давайте преобразуем json.Number в int64 и float64 с помощью методов Int64 и Float64:

gopackage main

import (
  "encoding/json"
  "fmt"
  "log"
)

func main() {
  data := []byte(`42.5`)
  var num json.Number
  err := json.Unmarshal(data, &num)
  if err != nil {
    log.Fatal(err)
  }

  intVal, err := num.Int64()
  if err != nil {
    fmt.Println("Cannot convert to int64")
  } else {
    fmt.Printf("Int64: %d\n", intVal)
  }

  floatVal, err := num.Float64()
  if err != nil {
    fmt.Println("Cannot convert to float64")
  } else {
    fmt.Printf("Float64: %f\n", floatVal)
  }
}

Результат выполнения кода:

go"Int64: 42"
"Float64: 42.500000"

Пример

Давайте используем json.Number для декодирования массива чисел с сохранением точности:

gopackage main

import (
  "encoding/json"
  "fmt"
)

func main() {
  data := []byte(`[12345678901234567890, 42.5, 100]`)
  var numbers []json.Number
  err := json.Unmarshal(data, &numbers)
  if err != nil {
    fmt.Println(err)
    return
  }
  for i, num := range numbers {
    res := num.String()
    fmt.Printf("numbers[%d]: %s\n", i, res)
  }
}

Результат выполнения кода:

go"numbers[0]: 12345678901234567890"
"numbers[1]: 42.5"
"numbers[2]: 100"

Смотрите также

  • функцию json.Unmarshal,
    которая декодирует данные JSON в значение Go
  • функцию json.Marshal,
    которая кодирует значение Go в JSON
  • тип json.RawMessage,
    который представляет необработанные данные JSON
  • функцию json.Valid,
    которая проверяет, является ли строка корректным JSON