Golang JSON 標準庫用法詳解

JSON (JavaScript Object Notation) 是一種輕量級的數據交換格式,Go語言的標準庫encoding/json提供了強大的JSON處理能力。下面我將詳細介紹各種用法并提供示例代碼。

1. 基本編碼(Marshal)

將Go數據結構轉換為JSON字符串。

package mainimport ("encoding/json""fmt""log"
)type Person struct {Name    string `json:"name"`          // 字段標簽指定JSON鍵名Age     int    `json:"age"`           // 基本類型字段Address string `json:"address"`       // 字符串字段Hobbies []string `json:"hobbies"`     // 切片字段IsAdmin bool   `json:"is_admin"`      // 布爾字段private string // 小寫開頭字段不會被導出
}func main() {// 創建一個Person實例p := Person{Name:    "Alice",Age:     30,Address: "123 Main St",Hobbies: []string{"reading", "hiking"},IsAdmin: true,private: "secret", // 這個字段不會被編碼}// 將結構體編碼為JSONjsonData, err := json.Marshal(p)if err != nil {log.Fatal(err)}fmt.Println(string(jsonData))// 輸出: {"name":"Alice","age":30,"address":"123 Main St","hobbies":["reading","hiking"],"is_admin":true}
}

2. 美化輸出(Indent)

使用MarshalIndent可以生成格式化的JSON輸出。

func main() {p := Person{Name:    "Bob",Age:     25,Address: "456 Oak Ave",Hobbies: []string{"gaming", "coding"},}// 使用MarshalIndent美化輸出jsonData, err := json.MarshalIndent(p, "", "  ")if err != nil {log.Fatal(err)}fmt.Println(string(jsonData))/*輸出:{"name": "Bob","age": 25,"address": "456 Oak Ave","hobbies": ["gaming","coding"],"is_admin": false}*/
}

3. 基本解碼(Unmarshal)

將JSON字符串解碼為Go數據結構。

func main() {// JSON字符串jsonStr := `{"name": "Charlie","age": 35,"address": "789 Pine Rd","hobbies": ["swimming", "photography"],"is_admin": true}`// 解碼JSON到Person結構體var p Personerr := json.Unmarshal([]byte(jsonStr), &p)if err != nil {log.Fatal(err)}fmt.Printf("%+v\n", p)// 輸出: {Name:Charlie Age:35 Address:789 Pine Rd Hobbies:[swimming photography] IsAdmin:true private:}
}

4. 處理未知結構的JSON

使用map[string]interface{}interface{}處理未知結構的JSON。

func main() {// 復雜的JSON數據jsonStr := `{"name": "Dave","age": 40,"metadata": {"department": "IT","role": "manager","permissions": ["read", "write", "delete"]}}`// 解碼到空接口var data interface{}err := json.Unmarshal([]byte(jsonStr), &data)if err != nil {log.Fatal(err)}// 類型斷言訪問數據m := data.(map[string]interface{})fmt.Println("Name:", m["name"])fmt.Println("Age:", m["age"])// 訪問嵌套數據metadata := m["metadata"].(map[string]interface{})fmt.Println("Department:", metadata["department"])fmt.Println("Permissions:", metadata["permissions"])
}

5. 流式處理(Encoder/Decoder)

對于大文件或網絡流,可以使用流式處理。

編碼器示例(Encoder)

package mainimport ("encoding/json""os"
)func main() {type Book struct {Title  string `json:"title"`Author string `json:"author"`Year   int    `json:"year"`}books := []Book{{"The Go Programming Language", "Alan A. A. Donovan", 2015},{"Effective Go", "The Go Authors", 2009},}// 創建文件file, err := os.Create("books.json")if err != nil {panic(err)}defer file.Close()// 創建JSON編碼器encoder := json.NewEncoder(file)// 設置縮進(可選)encoder.SetIndent("", "  ")// 編碼數據到文件err = encoder.Encode(books)if err != nil {panic(err)}
}

解碼器示例(Decoder)

package mainimport ("encoding/json""fmt""os"
)func main() {// 打開JSON文件file, err := os.Open("books.json")if err != nil {panic(err)}defer file.Close()// 創建JSON解碼器decoder := json.NewDecoder(file)var books []struct {Title  string `json:"title"`Author string `json:"author"`}// 解碼JSON數據err = decoder.Decode(&books)if err != nil {panic(err)}// 打印結果for _, book := range books {fmt.Printf("%s by %s\n", book.Title, book.Author)}
}

6. 自定義編碼/解碼

可以通過實現json.Marshalerjson.Unmarshaler接口來自定義編碼和解碼行為。

package mainimport ("encoding/json""fmt""strings""time"
)// 自定義時間格式
type CustomTime struct {time.Time
}const layout = "2006-01-02"// 實現Marshaler接口
func (ct CustomTime) MarshalJSON() ([]byte, error) {return []byte(`"` + ct.Time.Format(layout) + `"`), nil
}// 實現Unmarshaler接口
func (ct *CustomTime) UnmarshalJSON(data []byte) error {s := strings.Trim(string(data), `"`)t, err := time.Parse(layout, s)if err != nil {return err}ct.Time = treturn nil
}type Event struct {Name      string     `json:"name"`Timestamp CustomTime `json:"timestamp"`
}func main() {// 編碼示例event := Event{Name:      "Product Launch",Timestamp: CustomTime{time.Now()},}jsonData, err := json.Marshal(event)if err != nil {panic(err)}fmt.Println(string(jsonData))// 輸出: {"name":"Product Launch","timestamp":"2023-04-01"}// 解碼示例jsonStr := `{"name":"Team Meeting","timestamp":"2023-04-15"}`var decodedEvent Eventerr = json.Unmarshal([]byte(jsonStr), &decodedEvent)if err != nil {panic(err)}fmt.Printf("%+v\n", decodedEvent)// 輸出: {Name:Team Meeting Timestamp:{Time:2023-04-15 00:00:00 +0000 UTC}}
}

7. 處理JSON標簽選項

JSON標簽可以包含額外的選項來控制編解碼行為。

package mainimport ("encoding/json""fmt"
)type User struct {ID        int    `json:"id"`                     // 常規字段Username  string `json:"username"`               // 常規字段Password  string `json:"-"`                      // 忽略字段Email     string `json:"email,omitempty"`        // 如果為空則忽略LastLogin int64  `json:"last_login,omitempty"`   // 如果為零值則忽略IsActive  bool   `json:"is_active,string"`      // 編碼為字符串
}func main() {user := User{ID:        1,Username:  "johndoe",Password:  "secret",LastLogin: 0,       // 零值IsActive:  true,}jsonData, err := json.Marshal(user)if err != nil {panic(err)}fmt.Println(string(jsonData))// 輸出: {"id":1,"username":"johndoe","is_active":"true"}
}

8. 處理HTML特殊字符

默認情況下,JSON編碼器會轉義HTML特殊字符。

package mainimport ("encoding/json""fmt"
)func main() {data := map[string]string{"message": "<script>alert('xss')</script>",}jsonData, err := json.Marshal(data)if err != nil {panic(err)}fmt.Println(string(jsonData))// 輸出: {"message":"\u003cscript\u003ealert('xss')\u003c/script\u003e"}
}

如果需要禁用HTML轉義:

package mainimport ("bytes""encoding/json""fmt"
)func main() {data := map[string]string{"message": "<script>alert('xss')</script>",}buf := new(bytes.Buffer)encoder := json.NewEncoder(buf)encoder.SetEscapeHTML(false) // 禁用HTML轉義err := encoder.Encode(data)if err != nil {panic(err)}fmt.Println(buf.String())// 輸出: {"message":"<script>alert('xss')</script>"}
}

9. 處理原始JSON消息(RawMessage)

json.RawMessage可以用來延遲解析或傳遞原始JSON數據。

package mainimport ("encoding/json""fmt"
)type Message struct {Type string          `json:"type"`Data json.RawMessage `json:"data"` // 原始JSON數據
}type TextContent struct {Text string `json:"text"`
}type ImageContent struct {URL  string `json:"url"`Alt  string `json:"alt"`
}func main() {// 模擬接收到的JSON消息jsonStr := `{"type": "image","data": {"url": "https://example.com/image.jpg","alt": "Example image"}}`var msg Messageerr := json.Unmarshal([]byte(jsonStr), &msg)if err != nil {panic(err)}switch msg.Type {case "text":var content TextContenterr = json.Unmarshal(msg.Data, &content)fmt.Println("Text:", content.Text)case "image":var content ImageContenterr = json.Unmarshal(msg.Data, &content)fmt.Println("Image URL:", content.URL, "Alt:", content.Alt)}// 輸出: Image URL: https://example.com/image.jpg Alt: Example image
}

10. 處理JSON數組

處理JSON數組數據。

package mainimport ("encoding/json""fmt"
)func main() {// JSON數組字符串jsonStr := `[{"name": "Alice", "age": 25},{"name": "Bob", "age": 30},{"name": "Charlie", "age": 35}]`// 解碼到結構體切片var people []struct {Name string `json:"name"`Age  int    `json:"age"`}err := json.Unmarshal([]byte(jsonStr), &people)if err != nil {panic(err)}for _, p := range people {fmt.Printf("%s is %d years old\n", p.Name, p.Age)}/*輸出:Alice is 25 years oldBob is 30 years oldCharlie is 35 years old*/
}

總結

Go的encoding/json包提供了強大的JSON處理能力,包括:

  1. 結構體與JSON的相互轉換(Marshal/Unmarshal)
  2. 流式處理(Encoder/Decoder)
  3. 自定義編解碼行為
  4. 處理復雜和動態JSON結構
  5. 各種標簽選項控制編解碼行為

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89114.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89114.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89114.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Day.42

hook函數&#xff1a; import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt torch.manual_seed(42) np.random.seed(42) 張量鉤子&#xff1a; x torch.tensor([2.0], requires_gradTrue) y x ** 2 z y ** 3 def tensor_hook…

【.net core】【sqlsugar】在where條件查詢時使用原生SQL

//初始化查詢 var query repository.IQueryable();//添加原生SQL WHERE條件 query query.Where(" fieldA < 123"); 對應調用ISugarQueryable接口類中&#xff1a; ISugarQueryable<T> Where(string whereString, object parameters null);

網絡 : 傳輸層【TCP協議】

網絡 : 傳輸層【TCP協議】 一、TCP協議段格式1.1 32位序號與確認號1.1.1 32位序號1.1.2 確認號 1.2 4位首部長度1.3 6位標志位1.4 16位窗口大小 二、確認應答(ACK)機制三、超時重傳機制四、連接管理機制4.1 三次握手(連接)listen的第二個參數 4.2 四次揮手(斷開連接)**TIME_WAI…

人大金倉Kingbase數據庫 Ksql: 未找到命令

人大金倉Kingbase數據庫 Ksql: 未找到命令 1. 定位 Kingbase 安裝目錄 Kingbase 數據庫通常安裝在 /kingbase/ES/V8/Server 目錄下。可以通過以下命令定位&#xff1a; cd /kingbase/ES/V8/Server2. 驗證 ksql 工具是否安裝成功 執行以下命令檢查 ksql 客戶端工具的版本信息…

Flask(四) 模板渲染render_template

文章目錄 &#x1f4e6; 過程詳解&#xff08;路由 <-> HTML 模板&#xff09;&#x1f9e0; 數據是怎么傳過去的&#xff1f;多變量示例 ? Jinja2 支持條件判斷、循環、模板繼承&#xff1a;? 安全性&#x1f512; Flask 默認也會對變量進行 HTML 轉義&#xff1a;&am…

[附源碼+數據庫+畢業論文+開題報告]基于Spring+MyBatis+MySQL+Maven+jsp實現的寵物領養管理系統,推薦!

摘 要 互聯網發展至今&#xff0c;無論是其理論還是技術都已經成熟&#xff0c;而且它廣泛參與在社會中的方方面面。它讓信息都可以通過網絡傳播&#xff0c;搭配信息管理工具可以很好地為人們提供服務。針對寵物領養信息管理混亂&#xff0c;出錯率高&#xff0c;信息安全性差…

【ArcGIS】水資源單項評價

【ArcGIS】水資源單項評價 一、水資源單項評價1、評價思路 二、操作步驟1、處理環境設置2、數據處理3、要素轉柵格4、水資源評價 一、水資源單項評價 1、評價思路 &#xff08;1&#xff09;省級層面宜選用四級/五級水資源分區或縣級行政區為評價單元&#xff0c;按照水資源總…

Windows環境下C語言匯編語言編輯器及環境安裝

安裝MinGw&#xff1a; 1.下載安裝文件 MinGW - 適用于 Windows 的極簡主義 GNU 下載 |SourceForge.net 點擊下載 下載之后就是如下圖的安裝文件 2.安裝 雙擊安裝文件進行安裝&#xff0c;點擊Install下一步 選擇安裝位置&#xff0c;默認是安裝在C盤&#xff0c;點擊Change…

【數據分析】分段邏輯回歸示例分析(模擬數據)

禁止商業或二改轉載,僅供自學使用,侵權必究,如需截取部分內容請后臺聯系作者! 文章目錄 介紹加載R包步驟 1:模擬數據步驟 2:構建邏輯回歸和分段模型步驟 3:計算預測值和置信區間步驟 4:提取 OR 和統計值步驟 5:繪圖展示結步驟 6:輸出圖片原始代碼總結系統信息參考介紹…

Webpack 構建過程詳解

Webpack 是一個功能強大的模塊打包工具,它能夠將項目中的各種資源(如 JavaScript、CSS、圖片等)打包成一個或多個文件,以便于在瀏覽器中運行。本文將以 Webpack 5 為例介紹它的構建過程: 1. 初始化階段 在這個階段,Webpack 從配置文件和命令行參數中讀取并解析配置。然…

Flutter基礎(UI監聽)

文本按鈕&#xff08;TextButton&#xff09; 文本按鈕是沒有邊框的按鈕&#xff0c;當點擊時會有漣漪效果。 TextButton(onPressed: () {// 點擊按鈕后要執行的代碼print(文本按鈕被點擊了);},child: Text(點擊我), ) 手勢檢測器&#xff08;GestureDetector&#xff09; …

Linux 下的 regulator 子系統

1、簡介 regulator 框架是 Linux 內核中用于管理電壓和電流調節器&#xff08;如 LDO、DCDC 轉換器等&#xff09;的一個子系統。它提供了一個抽象層&#xff0c;使得驅動程序和內核的其他部分可以以一致的方式與調節器進行交互&#xff0c;而無需了解底層硬件的細節。 主要功能…

12345政務熱線系統:接訴即辦,賦能智慧城市治理

一、12345熱線&#xff1a;民情直通車&#xff0c;治理新引擎 “12345”政務熱線是黨委政府了解社情民意、解決群眾合理訴求、傾聽批評建議、改進工作作風的重要渠道。當前&#xff0c;全國各城市已基本建成12345政務服務熱線體系&#xff0c;形成“接訴即辦”的高效響應機制。…

【SpringBoot核心】Spring Boot + MyBatis 深度整合與最佳實踐

目錄 引言Spring Boot 基礎回顧MyBatis 核心概念解析Spring Boot 整合 MyBatisMyBatis 高級特性Spring Boot + MyBatis 最佳實踐性能優化與擴展實戰案例:電商系統開發常見問題與解決方案總結與展望1. 引言 1.1 技術背景與現狀 在現代企業級應用開發中,數據持久化是一個核心…

力扣第77題-組合-力扣第78題-子集

力扣鏈接:77. 組合 - 力扣&#xff08;LeetCode&#xff09; 給定兩個整數 n 和 k&#xff0c;返回范圍 [1, n] 中所有可能的 k 個數的組合。 你可以按 任何順序 返回答案。 示例 1&#xff1a; 輸入&#xff1a;n 4, k 2 輸出&#xff1a; [[2,4],[3,4],[2,3],[1,2],[1,3…

嵌入式MTD設備與Flash管理解析

理解MTD是嵌入式系統中處理Flash存儲的關鍵一步&#xff01;我來幫你梳理清楚&#xff1a; MTD 是什么&#xff1f; MTD 是 Memory Technology Device 的縮寫&#xff0c;中文常譯為內存技術設備。它是 Linux 內核及其衍生系統&#xff08;如嵌入式 Linux&#xff09;中用于管…

基于 GEE 利用 Sentinel-2 數據計算并下載植被指數數據

目錄 1 植被指數 2 完整代碼 3 運行結果 1 植被指數 植被指數全名NDVI歸一化差值植被指數GNDVI綠色歸一化差值植被指數EVI增強植被指數EVI2雙波段增強植被指數DVI差值植被指數GDVI綠色差植被值指數RVI比值植被指數SAVI土壤調整植被指數OSAVI優化土壤調整植被指數MSAVI修改…

python基礎23(2025.6.29)分布式爬蟲(增量式爬蟲去重)redis應用_(未完成!)

本次寫一個爬取網易新聞的案例。因為redis能處理高并發&#xff0c;存儲數據也可以&#xff0c;故不用mysql。而且新聞網站容易更新很多&#xff0c;而mysql只能持久化存儲。 import scrapy import re import json import redis # 用它來去除重復, 記錄訪問過的urlclass Wang…

Springboot 集成 SpringState 狀態機

Springboot 集成 SpringState 狀態機 1.SpringState 簡介2.狀態機示例2.1 項目結構和依賴包2.2 定義事件類和狀態類2.3 Spring 事件監聽器2.4 狀態機持久化類2.4.1 Redis 狀態機持久化容器2.4.2 Redis 配置2.4.3 狀態機監聽器 2.5 裝機器容器2.6 狀態機事件發送器2.7 狀態機配置…

實戰四:基于PyTorch實現貓狗分類的web應用【2/3】

?一、需求描述 實戰四分為三部分來實現&#xff0c;第二部分是基于PyTorch的貓狗圖像可視化訓練的教程&#xff0c;實現了一個完整的貓狗分類模型訓練流程&#xff0c;使用預訓練的ResNet50模型進行遷移學習&#xff0c;并通過SwanLab進行實驗跟蹤。 效果圖 ?二、實現思路 …