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

《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.xdnf.cn/news/17452.html

相关文章:

  • 创建降阶模型用于搅拌槽中的涡流预测
  • 线性代数1000题学习笔记
  • 【机器学习深度学习】Embedding 模型详解:从基础原理到实际应用场景
  • NLP——TF-IDF算法
  • 《从零构建大语言模型》学习笔记4,注意力机制1
  • ADK(Agent Development Kit)【2】调用流程详解
  • 【东枫科技】 FR2 Massive MIMO 原型验证与开发平台,8*8通道
  • NLP学习开始-02逻辑回归
  • 【软件测试】性能测试 —— 工具篇 JMeter 介绍与使用
  • C++高频知识点(十九)
  • 【AI论文】LongVie:多模态引导的可控超长视频生成
  • 嵌套-列表存储字典,字典存储列表,字典存储字典
  • InfluxDB 在物联网设备数据采集与分析中的应用(一)
  • Python爬虫-爬取政务网站的文档正文内容和附件数据
  • 如何解决线上gc频繁的问题?
  • 在Ansys Simplorer中设计三相逆变器,并与Maxwell FEA耦合,实现160kW PMSM
  • Day 10: Transformer完整架构详解 - 从位置编码到编解码器的全面剖析
  • Excel常用功能函数
  • 重学React(四):状态管理二
  • 攻击者瞄准加密技术的基础:智能合约
  • Dify集成 Echarts 实现智能数据报表集成与展示实战详解
  • 第三章-提示词:从0到1,提示词实训全攻略,解锁大语言模型无限潜能(14/36)
  • 深度解析 Spring Boot 循环依赖:原理、源码与解决方案
  • Python vs MATLAB:智能体开发实战对比
  • JavaScript 变量:数据存储的核心机制
  • 生产环境中Spring Cloud Sleuth与Zipkin分布式链路追踪实战经验分享
  • 消息生态系统全景解析:技术架构、核心组件与应用场景
  • Tomcat报错-chcon无法关联自启脚本
  • MySQL(189)如何分析MySQL的锁等待问题?
  • 采用GPT5自动规划实现番茄计时器,极简提示词,效果达到产品级