当前位置: 首页 > news >正文

golang学习笔记:标准库encoding

在Go语言中,encoding包及其子包是用来处理不同编码格式的。

常用子包

encoding/json - JSON编码解码

基本编码解码

import "encoding/json"type User struct {Name  string `json:"name"`Age   int    `json:"age,omitempty"`Email string `json:"email,omitempty"`
}// 编码(序列化)
user := User{Name: "Alice", Age: 25}
data, err := json.Marshal(user)             // {"name":"Alice","age":25}
data, err = json.MarshalIndent(user, "", "  ") // 格式化输出// 解码(反序列化)
var decodedUser User
err = json.Unmarshal(data, &decodedUser)

流式处理

// 编码到 Writer
err := json.NewEncoder(file).Encode(user)// 从 Reader 解码
err := json.NewDecoder(file).Decode(&user)

自定义编码

type CustomTime time.Timefunc (ct *CustomTime) MarshalJSON() ([]byte, error) {return json.Marshal(time.Time(*ct).Format("2006-01-02"))
}func (ct *CustomTime) UnmarshalJSON(data []byte) error {var str stringif err := json.Unmarshal(data, &str); err != nil {return err}t, err := time.Parse("2006-01-02", str)if err != nil {return err}*ct = CustomTime(t)return nil
}

原始消息处理

type Response struct {Status int             `json:"status"`Data   json.RawMessage `json:"data"` // 延迟解析
}var resp Response
json.Unmarshal(data, &resp)// 根据类型解析 Data
if resp.Status == 200 {var user Userjson.Unmarshal(resp.Data, &user)
} else {var errorMsg map[string]stringjson.Unmarshal(resp.Data, &errorMsg)
}

encoding/xml - XML编码解码

基本XML处理

import "encoding/xml"type Book struct {XMLName xml.Name `xml:"book"`Title   string   `xml:"title"`Author  string   `xml:"author"`Year    int      `xml:"year,attr"`Price   float64  `xml:"price"`
}// 编码
book := Book{Title: "Go Programming", Author: "Alice", Year: 2023}
data, err := xml.Marshal(book)
data, err = xml.MarshalIndent(book, "", "  ")// 解码
var decodedBook Book
err = xml.Unmarshal(data, &decodedBook)

XML 特性

type Catalog struct {XMLName xml.Name `xml:"catalog"`Books   []Book   `xml:"book"`Comment string   `xml:",comment"`        // 注释ID      string   `xml:"id,attr"`         // 属性Data    string   `xml:",chardata"`       // 字符数据Inner   string   `xml:",innerxml"`       // 原始 XMLOmit    string   `xml:",omitempty"`      // 空值忽略
}

流式处理

// 编码到 Writer
err := xml.NewEncoder(file).Encode(catalog)// 从 Reader 解码
err := xml.NewDecoder(file).Decode(&catalog)

encoding/base64 - Base64编码

标准Base64

import "encoding/base64"data := []byte("hello world")// 编码
encoded := base64.StdEncoding.EncodeToString(data)
// "aGVsbG8gd29ybGQ="// 解码
decoded, err := base64.StdEncoding.DecodeString(encoded)

URL安全的Base64

// URL 和文件名安全编码
urlEncoded := base64.URLEncoding.EncodeToString(data)
// "aGVsbG8gd29ybGQ="// 原始标准编码(无填充)
rawEncoded := base64.RawStdEncoding.EncodeToString(data)

自定义编码

// 自定义编码器
customEncoding := base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
encoded := customEncoding.EncodeToString(data)

encoding/hex - 十六进制编码

基本十六进制转换

import "encoding/hex"data := []byte("Hello")// 编码为十六进制字符串
encoded := hex.EncodeToString(data)
// "48656c6c6f"// 解码十六进制字符串
decoded, err := hex.DecodeString(encoded)

格式化输出

// 带空格的分隔格式
src := []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f}
dst := make([]byte, hex.EncodedLen(len(src)))
hex.Encode(dst, src)
// "48656c6c6f"// 解码到字节切片
srcStr := "48 65 6c 6c 6f"
dst := make([]byte, hex.DecodedLen(len(srcStr)))
_, err := hex.Decode(dst, []byte(srcStr))

encoding/csv - CSV文件处理

读取 CSV

import "encoding/csv"// 从字符串读取
csvData := `name,age,city
Alice,30,New York
Bob,25,London`reader := csv.NewReader(strings.NewReader(csvData))
records, err := reader.ReadAll()
// [["name" "age" "city"] ["Alice" "30" "New York"] ["Bob" "25" "London"]]// 逐行读取
reader = csv.NewReader(file)
for {record, err := reader.Read()if err == io.EOF {break}if err != nil {log.Fatal(err)}// 处理 record
}

写入CSV

// 写入到 Writer
var buf bytes.Buffer
writer := csv.NewWriter(&buf)records := [][]string{{"name", "age", "city"},{"Alice", "30", "New York"},{"Bob", "25", "London"},
}err := writer.WriteAll(records)
writer.Flush() // 确保数据写入

CSV配置

reader := csv.NewReader(file)
reader.Comma = ';'           // 自定义分隔符
reader.Comment = '#'         // 注释字符
reader.FieldsPerRecord = 3   // 每行字段数
reader.TrimLeadingSpace = true // 修剪前导空格writer := csv.NewWriter(file)
writer.UseCRLF = true        // 使用 Windows 换行符

encoding/gob - Go二进制编码

基本使用

import "encoding/gob"type Person struct {Name stringAge  int
}// 编码
var network bytes.Buffer
person := Person{Name: "Alice", Age: 30}
encoder := gob.NewEncoder(&network)
err := encoder.Encode(person)// 解码
var decodedPerson Person
decoder := gob.NewDecoder(&network)
err = decoder.Decode(&decodedPerson)

注册类型

// 注册自定义类型
gob.Register(Person{})// 编码接口类型
var buffer bytes.Buffer
encoder := gob.NewEncoder(&buffer)var data interface{} = Person{Name: "Bob", Age: 25}
err := encoder.Encode(&data)

使用示例

配置管理

package configimport ("encoding/json""os"
)type Config struct {Database DatabaseConfig `json:"database"`Server   ServerConfig   `json:"server"`Features []string       `json:"features"`
}type DatabaseConfig struct {Host     string `json:"host"`Port     int    `json:"port"`Username string `json:"username"`Password string `json:"password"`
}type ServerConfig struct {Port    int    `json:"port"`Timeout int    `json:"timeout"`Env     string `json:"env"`
}func LoadConfig(path string) (*Config, error) {file, err := os.Open(path)if err != nil {return nil, err}defer file.Close()var config Configdecoder := json.NewDecoder(file)if err := decoder.Decode(&config); err != nil {return nil, err}return &config, nil
}func SaveConfig(config *Config, path string) error {file, err := os.Create(path)if err != nil {return err}defer file.Close()encoder := json.NewEncoder(file)encoder.SetIndent("", "  ")return encoder.Encode(config)
}

API 响应处理

package apiimport ("encoding/json""net/http"
)type Response struct {Success bool        `json:"success"`Data    interface{} `json:"data,omitempty"`Error   string      `json:"error,omitempty"`Code    int         `json:"code,omitempty"`
}func WriteJSON(w http.ResponseWriter, status int, data interface{}) error {w.Header().Set("Content-Type", "application/json")w.WriteHeader(status)return json.NewEncoder(w).Encode(data)
}func WriteSuccess(w http.ResponseWriter, data interface{}) error {resp := Response{Success: true, Data: data}return WriteJSON(w, http.StatusOK, resp)
}func WriteError(w http.ResponseWriter, status int, errMsg string) error {resp := Response{Success: false, Error: errMsg, Code: status}return WriteJSON(w, status, resp)
}func ReadJSON(r *http.Request, v interface{}) error {return json.NewDecoder(r.Body).Decode(v)
}

数据加密存储

package storageimport ("encoding/base64""encoding/json""crypto/aes""crypto/cipher"
)type SecureStorage struct {key []byte
}func NewSecureStorage(key string) *SecureStorage {// 确保密钥长度合适keyBytes := make([]byte, 32)copy(keyBytes, []byte(key))return &SecureStorage{key: keyBytes}
}func (s *SecureStorage) EncryptAndStore(data interface{}) (string, error) {// 序列化为 JSONjsonData, err := json.Marshal(data)if err != nil {return "", err}// 加密block, err := aes.NewCipher(s.key)if err != nil {return "", err}gcm, err := cipher.NewGCM(block)if err != nil {return "", err}nonce := make([]byte, gcm.NonceSize())encrypted := gcm.Seal(nonce, nonce, jsonData, nil)// Base64 编码return base64.URLEncoding.EncodeToString(encrypted), nil
}func (s *SecureStorage) DecryptAndLoad(encryptedStr string, v interface{}) error {// Base64 解码encrypted, err := base64.URLEncoding.DecodeString(encryptedStr)if err != nil {return err}// 解密block, err := aes.NewCipher(s.key)if err != nil {return err}gcm, err := cipher.NewGCM(block)if err != nil {return err}nonceSize := gcm.NonceSize()nonce, ciphertext := encrypted[:nonceSize], encrypted[nonceSize:]jsonData, err := gcm.Open(nil, nonce, ciphertext, nil)if err != nil {return err}// 反序列化return json.Unmarshal(jsonData, v)
}

消息序列化系统

package messagingimport ("encoding/gob""encoding/json""encoding/xml""bytes""fmt"
)type Message struct {Type    string      `json:"type" xml:"type"`Payload interface{} `json:"payload" xml:"payload"`
}type Serializer interface {Serialize(interface{}) ([]byte, error)Deserialize([]byte, interface{}) error
}type JSONSerializer struct{}func (j JSONSerializer) Serialize(v interface{}) ([]byte, error) {return json.Marshal(v)
}func (j JSONSerializer) Deserialize(data []byte, v interface{}) error {return json.Unmarshal(data, v)
}type XMLSerializer struct{}func (x XMLSerializer) Serialize(v interface{}) ([]byte, error) {return xml.Marshal(v)
}func (x XMLSerializer) Deserialize(data []byte, v interface{}) error {return xml.Unmarshal(data, v)
}type GobsSerializer struct{}func (g GobsSerializer) Serialize(v interface{}) ([]byte, error) {var buf bytes.Bufferencoder := gob.NewEncoder(&buf)if err := encoder.Encode(v); err != nil {return nil, err}return buf.Bytes(), nil
}func (g GobsSerializer) Deserialize(data []byte, v interface{}) error {buf := bytes.NewBuffer(data)decoder := gob.NewDecoder(buf)return decoder.Decode(v)
}type MessageBus struct {serializer Serializer
}func NewMessageBus(serializer Serializer) *MessageBus {return &MessageBus{serializer: serializer}
}func (m *MessageBus) Send(message Message) ([]byte, error) {return m.serializer.Serialize(message)
}func (m *MessageBus) Receive(data []byte) (*Message, error) {var message Messageif err := m.serializer.Deserialize(data, &message); err != nil {return nil, err}return &message, nil
}

性能优化技巧

1.重用编码器/解码器

// 不推荐:每次创建新的编码器
func process(data interface{}) ([]byte, error) {return json.Marshal(data)
}// 推荐:重用编码器
var encoderBuffer bytes.Buffer
var encoder = json.NewEncoder(&encoderBuffer)func processOptimized(data interface{}) ([]byte, error) {encoderBuffer.Reset()if err := encoder.Encode(data); err != nil {return nil, err}return encoderBuffer.Bytes(), nil
}

2.预分配缓冲区

func encodeLargeData(data []interface{}) ([]byte, error) {var buf bytes.Bufferbuf.Grow(1024 * 1024) // 预分配 1MBencoder := json.NewEncoder(&buf)if err := encoder.Encode(data); err != nil {return nil, err}return buf.Bytes(), nil
}
http://www.dtcms.com/a/520543.html

相关文章:

  • Go语言实战教学:从一个混合定时任务调度器(Crontab)深入理解Go的并发、接口与工程哲学
  • 如何做原创小说网站广州商城网站制作网站
  • 让线程按指定顺序运行
  • 定制手机网站开发显示网站翻页代码
  • CoAlbum:多级缓存与性能对比
  • 【算法专题训练】27、树的层序遍历
  • 网站导入wordpress基层建设是哪个网站的
  • 第6章—手动移植创建STM32工程
  • Android Bluetooth 蓝牙通信
  • 简述一般网站开发方式广州三合一企业网站哪家好
  • 网站建设邀标函专业的外贸建站公司
  • C++ STL(标准模板库)深度解析:从基础到实践
  • 压缩与缓存调优实战指南:从0到1根治性能瓶颈(二)
  • Linux小课堂: SSH 配置文件详解之全局与局部 Config 文件的语义梳理与技术深化
  • 6-2〔O҉S҉C҉P҉ ◈ 研记〕❘ 客户端攻击▸利用WORD宏让客户端执行命令
  • 网站页面设计报价xampp做网站设置
  • 制作 网站 盈利怎么看网站到期时间
  • Qt6.10 | Qt Bluetooth 蓝牙
  • 网站自动化开发无极官方网站下载
  • 基于 docker compose 进行部署PandaWiki
  • 哪里建设网站设计服务
  • Python - 100天从新手到大师:第五十八天 Python中的并发编程(1-3)
  • C语言-动态内存分配
  • 多个PDF文档如何批量删除页眉处的多余信息
  • 网站服务器空间大小网站自适应宽度
  • 静态网站什么样做个简单的网站
  • EtherCAT转EtherNet/IP工业PLC网关:实现PLC与底层设备的无缝协同控制
  • 群晖边缘存储方案,让数据更近、更快、更安全
  • Python电力负荷预测:LSTM、GRU、DeepAR、XGBoost、Stacking、ARIMA结合多源数据融合与SHAP可解释性的研究
  • 做网站送的小程序有什么用多多进宝怎么推广赚钱