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

《Go小技巧易错点100例》第三十七篇

本期分享:

1.Go结构体非导出字段不会被序列化

2.Go语言的字符串是不可变

3.代码块{}的作用范围


Go结构体非导出字段不会被序列化

在Go语言中,结构体字段的可见性(是否以大写字母开头)会影响JSON序列化和反序列化的行为。这是Go语言的一个核心特性,与包的可见性规则一致。

基本规则

可导出字段(大写字母开头)会被JSON包序列化和反序列化,而非导出字段(小写字母开头)会被JSON包忽略。

示例代码
package mainimport ("encoding/json""fmt"
)type Person struct {Name string `json:"name"` // 可导出,会被序列化age  int    `bson:"age"`  // 非导出,会被忽略
}func main() {// 序列化p := Person{Name: "Alice", age: 30}jsonData, _ := json.Marshal(p)fmt.Println(string(jsonData)) // 输出: {"Name":"Alice"}// 反序列化var p2 Person_ = json.Unmarshal([]byte(`{"Name":"Bob","age":40}`), &p2)fmt.Printf("%+v\n", p2) // 输出: {Name:Bob age:0}
}
关键点说明

序列化时只有Name字段被包含在JSON输出中age字段由于是非导出的,不会被包含

反序列化时即使JSON数据中包含age字段,由于结构体中对应字段是非导出的,该值会被忽略反序列化后age字段保持其零值(int类型的零值是0)

如果需要处理非导出字段,可以考虑以下方法

  • 使用json:"-"标签显式忽略字段
  • 实现自定义的MarshalJSON和UnmarshalJSON方法

这种设计是Go语言刻意为之的,它强制开发者明确哪些字段应该被暴露给外部系统,有助于提高代码的安全性和可维护性。

Go语言中的字符串是不可变

下面这段Go代码的执行会报错,因为Go语言中的字符串是不可变的(immutable)。具体分析如下:

func main() {str := "hello"str[0] = 'x'  // 这里会编译错误fmt.Println(str)
}

编译时会直接报错:cannot assign to str[0] (不能对字符串的字符进行赋值)

原因是Go中的字符串是只读的字节切片,不能直接修改其中的字符,如果你想修改字符串中的字符,可以先将字符串转换为[]byte或[]rune切片,修改后再转回字符串:

func main() {str := "hello"bytes := []byte(str)bytes[0] = 'x'str = string(bytes)fmt.Println(str) // 输出: xello
}

在Go中,字符串的不可变性是语言设计的一个重要特性,这有助于保证字符串操作的安全性和线程安全性。

代码块{}的作用范围

func main() {x := 1{x := 2fmt.Print(x)}fmt.Println(x)
}

这段Go代码的执行结果是:

21

详细解释:

首先看代码结构分析:

func main() {x := 1          // 外层x,值为1{x := 2      // 内层x,与外层x是不同的变量fmt.Print(x) // 打印内层x的值2}fmt.Println(x)  // 打印外层x的值1
}

执行过程:

首先声明外层变量x并赋值为1,进入内部代码块,声明新的变量x并赋值为2(这是一个新的变量,与外层x同名但不同一)

打印内部x的值2fmt.Print不换行)
退出内部代码块后,打印外层x的值1fmt.Println会换行)

Go语言的变量作用域规则

使用:=会在当前作用域创建新变量,内部代码块中的x := 2是新建了一个变量,不是修改外层的x,如果想修改外层x的值,应该使用赋值=而不是声明:=
如果想修改外层变量,代码应该这样写:

func main() {x := 1{x = 2      // 注意这里使用=而不是:=fmt.Print(x)}fmt.Println(x)
}

输出: 22

本篇结束~

http://www.dtcms.com/a/324651.html

相关文章:

  • 深度解析Linux设备树(DTS):设计原理、实现框架与实例分析
  • 阿里云ECS云服务器临时升级带宽方法
  • JP3-4-MyClub后台前端(三)
  • 胖虎的菜品
  • 一劳永逸解决Mayplotlib绘图中中文字体显示乱码的问题
  • 嵌入式软件分层架构的设计原理与实践验证(有限状态机理解及结构体封装理解)
  • 进度、质量、安全的关系随笔
  • 力扣面试150(52/150)
  • NY155NY170美光固态闪存NY175NY184
  • Zabbix优化指南:提升监控效率与性能
  • Pytorch深度学习框架实战教程-番外篇07-Pytorch优化器详解和实战指南
  • 机器学习——DBSCAN
  • 【人工智能99问】LLaMA的训练过程和推理过程是怎么样的?(22/99)
  • 【GPT入门】第43课 使用LlamaFactory微调Llama3
  • AI大模型提示词工程完全指南:从入门到精通
  • 【自用】JavaSE--IO流(二)--缓冲流、转换流、打印流、数据流、序列化流、IO框架
  • 硬件开发_基于STM32单片机的智能电梯系统
  • 【RocketMQ 生产者和消费者】- ConsumeMessageConcurrentlyService 并发消费消息
  • 自然语言处理入门路线-实践篇
  • AutoCAD 2026 的主要功能
  • 如何选择适合自己电商业务的 API?​
  • 解决RuoYi-Cloud项目ruoyi-system模块启动失败问题以及Naco容器部署问题
  • 【21】OpenCV C++实战篇——OpenCV C++案例实战二十七《角度测量》
  • SpringAI智能航空助手实战<Demo>
  • 《算法导论》第 17 章 - 摊还分析
  • XGBoost 与 GBDT 的比较:改进与性能提升
  • MATLAB绘制水的蒸汽压曲线(Antoine方程)
  • GitHub上为什么采用Gradle编译要多于Maven
  • DBSACN算法的一些应用
  • 【算法】图的 深度优先搜索(DFS)与 广度优先搜索(BFS)