以身作則,JSON元帥和Unmarshal
在Go 語言中,encoding/json 包用於處理JSON 的序列化和反序列化。 1. 結構體字段需首字母大寫才能被訪問,通過json:"name" 設置鍵名,omitempty 在值為零值時省略字段,json:"-" 忽略字段;2. 使用json.Marshal 將結構體、map 或切片轉換為JSON 字符串,使用json.Unmarshal 將JSON 數據解析到變量中;3. 反序列化到interface{} 時,數字默認為float64 類型,需通過類型斷言轉換;4. 嵌套結構體可正常序列化,內嵌結構體會被展開;5. 始終檢查Marshal 和Unmarshal 的錯誤,常見問題包括JSON 格式錯誤、類型不匹配和非導出字段。正確使用struct tag 和數據結構可靈活處理各類JSON 場景。
在Go 語言中, encoding/json
包提供了對JSON 數據的序列化(marshal)和反序列化(unmarshal)支持。下面通過幾個常見的例子來演示如何使用json.Marshal
和json.Unmarshal
。

✅ 基本結構體的Marshal 與Unmarshal
package main import ( "encoding/json" "fmt" "log" ) type Person struct { Name string `json:"name"` Age int `json:"age"` Email string `json:"email,omitempty"` } func main() { // 示例1: Marshal 結構體→ JSON p := Person{ Name: "Alice", Age: 30, Email: "alice@example.com", } data, err := json.Marshal(p) if err != nil { log.Fatal(err) } fmt.Printf("Marshal result: %s\n", data) // 示例2: Unmarshal JSON → 結構體jsonData := `{"name":"Bob","age":25,"email":"bob@example.com"}` var p2 Person err = json.Unmarshal([]byte(jsonData), &p2) if err != nil { log.Fatal(err) } fmt.Printf("Unmarshal result: % v\n", p2) }
輸出:
Marshal result: {"name":"Alice","age":30,"email":"alice@example.com"} Unmarshal result: {Name:Bob Age:25 Email:bob@example.com}
注意:
json:"name"
指定字段在JSON 中的鍵名。omitempty
表示如果字段為零值(如空字符串、0、nil等),則序列化時省略。
✅ 處理map 的Marshal 和Unmarshal
// Marshal map → JSON m := map[string]interface{}{ "name": "Charlie", "age": 35, "tags": []string{"go", "dev"}, } data, _ := json.Marshal(m) fmt.Printf("Map to JSON: %s\n", data) // Unmarshal JSON → map var m2 map[string]interface{} jsonData := `{"name":"David","age":28,"active":true}` json.Unmarshal([]byte(jsonData), &m2) fmt.Printf("JSON to map: % v\n", m2) // 注意:map 中的數字默認解析為float64 if age, ok := m2["age"].(float64); ok { fmt.Println("Age:", int(age)) }
輸出:
Map to JSON: {"age":35,"name":"Charlie","tags":["go","dev"]} JSON to map: map[age:28 name:David active:true] Age: 28
⚠️ 注意:
json.Unmarshal
解析到interface{}
時,數字默認是float64
類型,需要類型斷言。
✅ 處理切片(Slice)和數組
people := []Person{ {Name: "Alice", Age: 30}, {Name: "Bob", Age: 25}, } // Marshal slice data, _ = json.Marshal(people) fmt.Printf("Slice to JSON: %s\n", data) // Unmarshal JSON array → slice jsonData := `[{"name":"Eve","age":22},{"name":"Frank","age":33}]` var people2 []Person json.Unmarshal([]byte(jsonData), &people2) fmt.Printf("JSON to slice: % v\n", people2)
輸出:
Slice to JSON: [{"name":"Alice","age":30},{"name":"Bob","age":25}] JSON to slice: [{Name:Eve Age:22 Email:} {Name:Frank Age:33 Email:}]
✅ 忽略空字段(omitempty 的使用)
p := Person{ Name: "Grace", Age: 0, // 零值// Email 留空} data, _ = json.Marshal(p) fmt.Printf("With omitempty: %s\n", data)
輸出:
With omitempty: {"name":"Grace"}
因為
Age
是0(int 的零值),但沒有omitempty
,所以仍會輸出。
omitempty
且為空,所以被省略。
如果你想連零值也省略,可以這樣寫:
Age int `json:"age,omitempty"`
✅ 嵌套結構體與自定義字段名
type Address struct { City string `json:"city"` Zip string `json:"zip"` } type User struct { Person `json:"person"` // 內嵌結構體Address Address `json:"address"` Password string `json:"-"` // 不參與序列化} u := User{ Person: Person{Name: "Helen", Age: 29}, Address: Address{City: "Beijing", Zip: "100000"}, Password: "secret123", } data, _ := json.Marshal(u) fmt.Printf("Nested struct: %s\n", data)
輸出:
Nested struct: {"person":{"name":"Helen","age":29},"address":{"city":"Beijing","zip":"100000"}}
- 內嵌結構體會被展開。
json:"-"
表示該字段不會被序列化或反序列化。
✅ 錯誤處理建議
使用json.Marshal
和json.Unmarshal
時,始終檢查錯誤:
data, err := json.Marshal(someValue) if err != nil { log.Printf("Marshal error: %v", err) return } err = json.Unmarshal(jsonData, &target) if err != nil { log.Printf("Unmarshal error: %v", err) return }
常見錯誤包括:
- JSON 格式不合法
- 類型不匹配(如期望數字但得到字符串)
- 字段不可導出(結構體字段必須大寫才能被json 包訪問)
小結:關鍵點
- 結構體字段必須首字母大寫才能被
json
包訪問。 - 使用
json:"fieldName"
自定義鍵名。 -
omitempty
可省略空值字段。 -
json:"-"
忽略字段。 -
map[string]interface{}
和[]interface{}
可用於動態結構,但注意類型斷言。 - 數字在
interface{}
中默認是float64
。
基本上就這些。實際開發中,結合struct tag
和合理的數據結構,就能靈活處理大多數JSON 場景。
以上是以身作則,JSON元帥和Unmarshal的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undress AI Tool
免費脫衣圖片

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

棧分配適用於生命週期明確的小型局部變量,自動管理、速度快但限制多;堆分配用於生命週期長或不確定的數據,靈活但有性能代價。 Go編譯器通過逃逸分析自動決定變量分配位置,若變量可能逃逸出當前函數作用域則分配至堆上。常見導致逃逸的情況包括:返回局部變量指針、賦值給接口類型、傳入goroutine。可通過-gcflags="-m"查看逃逸分析結果。使用指針時應關注變量生命週期,避免不必要的逃逸。

編寫KubernetesOperator的最有效方式是使用Go語言結合Kubebuilder和controller-runtime。 1.理解Operator模式:通過CRD定義自定義資源,編寫控制器監聽資源變化並執行調和循環以維護期望狀態。 2.使用Kubebuilder初始化項目並創建API,自動生成CRD、控制器和配置文件。 3.在api/v1/myapp_types.go中定義CRD的Spec和Status結構體,運行makemanifests生成CRDYAML。 4.在控制器的Reconcil

TooptimizeGoapplicationsinteractingwithPostgreSQLorMySQL,focusonindexing,selectivequeries,connectionhandling,caching,andORMefficiency.1)Useproperindexing—identifyfrequentlyqueriedcolumns,addindexesselectively,andusecompositeindexesformulti-columnquer

gRPC-Web瀏覽器端互通需配置中間件。 1.使用gRPC-Gateway做反向代理,將gRPC接口轉為JSON HTTP形式,並通過proto註解定義路由;2.更直接方案是使用Envoy,原生支持gRPC-Web並轉換為標準gRPC請求;3.Go後端正常實現gRPC接口,前端引入grpc-web客戶端庫調用;4.配置CORS解決跨域問題,包括允許來源、方法、頭信息及處理OPTIONS請求。正確配置後,前後端通信順暢。

在Go中遍歷字符串字符推薦使用forrange循環或轉為[]rune處理,避免直接按字節遍歷。 1.使用forrange循環可自動處理UTF-8編碼,返回字符(rune)及字節索引;2.轉為[]rune可實現索引訪問或修改字符,但會帶來內存分配和復制的代價;3.直接按字節遍歷可能導致字符拆分錯誤,僅適用於底層字節操作場景。

在Go語言中,選擇buffered或unbufferedchannel取決於是否需要同步通信。 1.Unbufferedchannel用於嚴格同步,發送和接收操作互相阻塞,適用於任務鏈、握手、實時通知等場景;2.Bufferedchannel允許異步處理,發送方僅在channel滿時阻塞,接收方在空時阻塞,適用於生產者-消費者模型、並發控制、數據流緩衝等場景;3.選擇時應根據是否需要發送和接收一一對應來決定,若任務必須立刻處理則用unbuffered,若允許排隊或併行處理則用buffered。掌握

Panic在Go中如同程序“心髒病發作”,recover可作為“急救工具”防止崩潰,但recover僅在defer函數中生效。 1.recover用於避免服務掛掉、記錄日誌、返回友好錯誤。 2.必須配合defer使用,僅對同goroutine生效,恢復後程序不回到panic點。 3.建議在頂層或關鍵入口使用,不濫用,優先使用error處理。 4.常見模式是封裝safeRun函數包裹可能panic的邏輯。掌握其使用場景與限制,才能正確發揮其作用。

在Go語言中,使用testing包的benchmark功能是進行代碼性能基準測試的標準方法。 1.編寫以Benchmark開頭的測試函數,並利用b.N控制運行次數,系統會自動調整輪次併計算平均耗時;2.控制變量避免干擾,初始化操作應放在計時器重置前,使用b.ResetTimer、b.StartTimer和b.StopTimer精確控制計時範圍;3.支持多版本對比與性能回歸檢測,可通過-bench指定多個測試函數,結合-count參數取多次運行平均值;4.可結合pprof工俱生成CPU性能分析報告,
