在Go语言中,json.Marshal 和 json.Decode 都是处理JSON数据的核心函数,但它们的用途和适用场景不同。以下是详细解释和示例代码:
json.Marshal
- 功能:将Go数据结构(如结构体、map或切片)序列化为JSON格式的字节切片(
[]byte)。
- 使用场景:当需要将Go数据转换为JSON字符串或字节流,以便发送到前端、存储到文件或通过网络传输时使用。
- 示例代码:
package main
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
user := User{Name: "Alice", Age: 30}
data, err := json.Marshal(user)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(data)) // 输出: {"name":"Alice","age":30}
}
json.Decode
- 功能:从输入流(如HTTP请求体、文件或字符串读取器)中读取JSON数据,并将其反序列化为Go数据结构。
- 使用场景:当从外部源(如HTTP请求、文件或网络连接)读取JSON数据并需要解析为Go变量时使用。它适用于流式数据或避免将整个JSON加载到内存的情况。
- 示例代码:
package main
import (
"encoding/json"
"fmt"
"strings"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
jsonData := `{"name":"Bob","age":25}`
reader := strings.NewReader(jsonData)
var user User
err := json.NewDecoder(reader).Decode(&user)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Name: %s, Age: %d\n", user.Name, user.Age) // 输出: Name: Bob, Age: 25
}
关键区别与选择
- 数据来源:如果JSON数据来自Go内存中的结构,使用
json.Marshal;如果来自输入流(如HTTP请求体),使用json.Decode。
- 性能考虑:
json.Decode 适用于大JSON数据或流式处理,因为它逐段读取而不需全加载;json.Marshal 适用于小到中等数据,需要完整序列化。
- 实际应用:在后端处理HTTP请求时,常用
json.Decode解析请求体,而用json.Marshal生成响应。
例如,在HTTP服务器中:
package main
import (
"encoding/json"
"net/http"
)
type RequestData struct {
Input string `json:"input"`
}
type ResponseData struct {
Result string `json:"result"`
}
func handler(w http.ResponseWriter, r *http.Request) {
var req RequestData
// 使用Decode解析请求体
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
// 处理数据
resp := ResponseData{Result: "Processed: " + req.Input}
w.Header().Set("Content-Type", "application/json")
// 使用Marshal生成响应
json.NewEncoder(w).Encode(resp)
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
总之,根据数据源和需求选择:Marshal用于Go到JSON的转换,Decode用于JSON到Go的转换(尤其从流中)。