我想用 json 標記獲取資料,其源具有 PascalCase 格式并將其保存到我的資料庫中。但是在進入資料庫之前,我想將PascalCase格式更改為snake_case格式。
我的問題似乎與這個問題相反(Golang Unmarshal an JSON response, then marshal with Struct field names)。但是我不想有 PascalCase,我想在名稱欄位中有蛇形大小寫
這是我撰寫的示例代碼:
package main
import (
"encoding/json"
"log"
)
// models data to save in DB
type (
Person struct {
FirstName string `json:"FirstName"`
LastName string `json:"LastName"`
Children []ChildData `json:"Children,omitempty"`
}
ChildData struct {
ChildName string `json:"ChildName"`
Age int `json:"Age"`
FavColor string `json:"FavColor"`
}
PersonOut struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Children []ChildData `json:"children,omitempty"`
}
ChildDataOut struct {
ChildName string `json:"child_name"`
Age int `json:"age"`
FavColor string `json:"fav_Color"`
}
)
// grisha is data from fetch API
var grisha = map[string]interface{}{
"FirstName": "Grisha",
"LastName": "Jeager",
"Children": []map[string]interface{}{
{
"ChildName": "Zeke",
"Age": 2,
"FavColor": "blue",
}, {
"ChildName": "Eren",
"Age": 3,
"FavColor": "red",
},
},
}
func getJsonfromAPI(data map[string]interface{}) []byte {
grishaJson, _ := json.MarshalIndent(grisha, "", " ")
return grishaJson
}
func parsingJSON(jsonInput []byte) {
var person Person
json.Unmarshal(jsonInput, &person)
out := PersonOut(person)
payload2, err := json.MarshalIndent(out, "", " ")
if err != nil {
panic(err)
}
log.Println(string(payload2))
}
func main() {
data := getJsonfromAPI(grisha)
parsingJSON(data)
}
我想要的結果就像
{
"first_name": "Grisha",
"last_name": "Jeager",
"children": [
{
"child_name": "Zeke",
"age": 2,
"fav_color": "blue"
},
{
"child_name": "Eren",
"age": 3,
"fav_color": "red"
}
]
}
但結果仍然在嵌套欄位中有 PascalCase:
{
"first_name": "Grisha",
"last_name": "Jeager",
"children": [
{
"ChildName": "Zeke",
"Age": 2,
"FavColor": "blue"
},
{
"ChildName": "Eren",
"Age": 3,
"FavColor": "red"
}
]
}
我想知道如何從解組 JSON 轉換嵌套結構的欄位名稱。
uj5u.com熱心網友回復:
只有當它們的基礎型別(忽略標簽)相同時,才能將一個結構轉換為另一個結構。如果基礎型別不相同,則無法進行轉換。
以 structS1和為例S2,在下面的代碼片段中,它們的底層型別是相同的,您可以將一個轉換為另一個:
type S1 struct {
Field T1
}
type S2 struct {
Field T1
}
type T1 string
_ = S2(S1{}) // ok
但是,在下一個片段中,它們的基礎型別并不相同,因此您不能將一個轉換為另一個:
type S1 struct {
Field T1
}
type S2 struct {
Field T2
}
type T1 string
type T2 string
_ = S2(S1{}) // cannot convert S1{} (value of type S1) to type S2
有關更多詳細資訊,請在此處閱讀有關轉換的規范:https ://go.dev/ref/spec#Conversions
因此,要在其基礎型別不相同的兩個結構之間進行轉換,您必須逐個欄位手動進行轉換。json.Marshaler但是,在 JSON 封送處理的情況下,您可以通過實作介面并讓各個實體“自我轉換”來使其變得更好。
type Person struct {
FirstName string `json:"FirstName"`
LastName string `json:"LastName"`
Children []ChildData `json:"Children"`
}
func (p Person) MarshalJSON() ([]byte, error) {
type T struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Children []ChildData `json:"children"`
}
return json.Marshal(T(p))
}
type ChildData struct {
ChildName string `json:"ChildName"`
Age int `json:"Age"`
FavColor string `json:"FavColor"`
}
func (d ChildData) MarshalJSON() ([]byte, error) {
type T struct {
ChildName string `json:"child_name"`
Age int `json:"age"`
FavColor string `json:"fav_color"`
}
return json.Marshal(T(d))
}
https://go.dev/play/p/UGJY5p490Gs
uj5u.com熱心網友回復:
https://go.dev/play/p/l4O8KBNrm1T
我們要:
- 將 Person 映射到 PersonOut
- 將 ChildData 映射到 ChildDataOut
func childDataToChildDataOut(childData ChildData) ChildDataOut {
return ChildDataOut{
ChildName: childData.ChildName,
Age: childData.Age,
FavColor: childData.FavColor,
}
}
func personToPersonOut(person Person) PersonOut {
var children []ChildDataOut
for _, childData := range person.Children {
childDataOut := childDataToChildDataOut(childData)
children = append(children, childDataOut)
}
return PersonOut{
FirstName: person.FirstName,
LastName: person.LastName,
Children: children,
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/466884.html
上一篇:如果goroutine只訪問不同的元素,我是否需要同步對地圖的訪問?[復制]
下一篇:GOENV只能使用OS環境設定
