我是 Golang 的菜鳥。我努力完成了一些事情。我正在處理以嵌套方式包含日期的 JSON 檔案。
我遇到了一些解決方法來將 JSON 資料中的日期解組,time.Time但我很難處理嵌套的日期。
以下代碼(在 StackOverflow 中獲得)很容易理解,因為它創建了一個用戶定義的函式來首先將時間物件決議為 a string,然后再決議為time.Timewith time.Parse。
package main
import (
"encoding/json"
"fmt"
"log"
"time"
)
const dateFormat = "2006-01-02"
const data = `{
"name": "Gopher",
"join_date": "2007-09-20"
}`
type User struct {
Name string `json:"name"`
JoinDate time.Time `json:"join_date"`
}
func (u *User) UnmarshalJSON(p []byte) error {
var aux struct {
Name string `json:"name"`
JoinDate string `json:"join_date"`
}
err := json.Unmarshal(p, &aux)
if err != nil {
return err
}
t, err := time.Parse(dateFormat, aux.JoinDate)
if err != nil {
return err
}
u.Name = aux.Name
u.JoinDate = t
return nil
}
func main() {
var u User
err := json.Unmarshal([]byte(data), &u)
if err != nil {
log.Fatal(err)
}
fmt.Println(u.JoinDate.Format(time.RFC3339))
}
到目前為止,一切都很好。現在我想擴展它以處理 JSON 中的嵌套日期欄位,如下例所示:
[{
"name": "Gopher",
"join_date": "2007-09-20",
"cashflow": [
{"date": "2021-02-25",
"amount": 100},
{"date": "2021-03-25",
"amount": 105}
]
}]
struct我想得到的是:
type Record []struct {
Name string `json:"name"`
JoinDate time.Time `json:"join_date"`
Cashflow []struct {
Date time.Time `json:"date"`
Amount int `json:"amount"`
} `json:"cashflow"`
}
謝謝您的幫助。
uj5u.com熱心網友回復:
要使用已有的模式解決此問題,您可以為內部結構撰寫一個單獨的解組函式。您可以通過將內部結構提升到其自己的命名結構,然后撰寫函式來做到這一點。
type CashflowRec struct {
Date time.Time `json:"date"`
Amount int `json:"amount"`
}
type Record struct {
Name string `json:"name"`
JoinDate time.Time `json:"join_date"`
Cashflow []CashflowRec `json:"cashflow"`
}
您已經展示了如何為 撰寫解組函式CashflowRec,它看起來與您的 User 函式幾乎相同。的解組功能Record將在呼叫時使用它
func (u *Record) UnmarshalJSON(p []byte) error {
var aux struct {
Name string `json:"name"`
JoinDate string `json:"join_date"`
Cashflow []CashflowRec `json:"cashflow"`
}
err := json.Unmarshal(p, &aux)
作業示例:https ://go.dev/play/p/1X7BJ4NETM0
除了 1我在看這個時學到的一些有趣的東西:因為您提供了自己的解組功能,所以您實際上不需要json原始結構中的標簽。這些是 json 包提供的解組器的提示。您可能仍然應該將它們留在里面,以防您以后必須對結構進行編組。這是沒有這些標簽的作業:https ://go.dev/play/p/G2VWopO_A3t
除了 2你可能會發現不使用它更簡單time.Time,而是創建一個自己的新型別,然后為該型別提供自己的解組器。這為您提供了一個有趣的選擇,即只撰寫一個 unmarshaller,但是這是否是一個勝利取決于您以后對結構所做的其他操作。仍然使用嵌套匿名結構的作業示例:https ://go.dev/play/p/bJUcaw3_r41
type dateType time.Time
type Record struct {
Name string `json:"name"`
JoinDate dateType `json:"join_date"`
Cashflow []struct {
Date dateType `json:"date"`
Amount int `json:"amount"`
} `json:"cashflow"`
}
func (c *dateType) UnmarshalJSON(p []byte) error {
var s string
if err := json.Unmarshal(p, &s); err != nil {
return err
}
t, err := time.Parse(dateFormat, s)
if err != nil {
return err
}
*c = dateType(t)
return nil
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/443009.html
