4.1 KiB
4.1 KiB
1.27版本变化
支持泛型方法
Go 1.27 虽然开放了泛型方法,但有明确的限制:
1.接口定义中不允许包含泛型方法。
2.拥有泛型方法的方法,不能用于实现接口。
// 普通结构体,本身没有任何泛型参数
type Serializer struct{}
// T 属于方法 Serialize,每个调用可以独立拥有不同的 T
func (s *Serializer) Serialize[T any](data T) string {
return fmt.Sprintf("%v", data)
}
// 使用:
sz := Serializer{}
// 同一个 sz 实例,每次调用都可以处理完全不同的类型!
str1 := sz.Serialize("hello") // 自动推导 T = string
str2 := sz.Serialize(123) // 自动推导 T = int
str3 := sz.Serialize(true) // 自动推导 T = bool
结构体字面量:字段选择器当 key
嵌套或匿名结构体中的字段,现在可以直接初始化,不必再一层层嵌套字面量
type Person struct {
Sex string
Name string
}
type Student struct {
StudentID int
Person
}
// Go 1.27 之前:必须显式嵌套 Person
s1 := Student{
StudentID: 1,
Person: Person{
Sex: "male",
Name: "张三",
},
}
// Go 1.27:嵌套结构体Person的字段可以直接当 key 用
s1 := Student{
StudentID: 1,
Sex: "male",
Name: "张三",
}
函数类型推断:从“手动挡”到“自动挡”
// Go 1.27 之前:必须手动写出类型实参 [int],否则编译报错
fn := IntToString(FormatToString[int])
formatter:= []IntToString{FormatToString[int]}
// Go 1.27 后:自动推导,不用手写
fn := IntToString(FormatToString)
formatter := []IntToString{FormatToString}
标准库更新:encoding/json/v2
Go 1.27 标准库中的 v1
encoding/json内部已经被改用 v2 引擎驱动,保留了 v1 的原始 API 签名和行为
新旧版本主要行为对比
| 场景 | encoding/json (v1) | encoding/json/v2 |
|---|---|---|
nil 切片/Map 序列化 |
转为 null |
转为 [] 和 {} (符合语义,防前端空指针) |
| 重复键处理 (Duplicate Keys) | 允许,后面的覆盖前面的 | 直接报错 (增强安全性,防 JSON 注入) |
| 非法 UTF-8 字符 | 格式化替换,静默忽略 | 直接报错 (要求严格符合规范) |
| 字段名匹配 (大小写敏感) | 默认忽略大小写匹配 | 默认严格匹配大小写 (提升解析性能) |
| 固定长度数组解包 | 长度不一致时自动截断或补零 | 必须与 JSON 数组长度严格相等,否则报错 |
支持可选项
| Options | 作用 |
|---|---|
json.FormatNilSliceAsNull(true) |
允许使用 v1 的 nil 行为 |
json.MatchCaseInsensitiveNames(true) |
允许忽略大小写 |
新增标签omitzero
| 维度 | omitempty | omitzero |
|---|---|---|
| 判断标准 | 是否为“空 (Empty)” (如:空字符串 ""、长度为 0 的切片/Map、false、0、指针 nil) |
是否为“ Go 类型的零值 (Zero Value)” (满足 reflect.Value.IsZero() 或实现 IsZero() bool 接口) |
| 结构体/时间类型处理 | 有重大缺陷,对非指针的结构体(如 time.Time)无效!依然会被序列化。 |
完美支持 未初始化的 time.Time{} 或任何嵌套结构体零值均会被正确跳过。 |
| 自定义类型零值 | 不支持自定义零值判断逻辑。 | 支持只要实现 IsZero() bool 方法即可自定义是否跳过。 |