Go语言中广泛使用的validator
库支持通过结构体标签定义校验规则。当内置规则无法满足需求时,我们可以轻松扩展自定义校验逻辑。
示例场景:验证用户年龄是否成年(≥18岁)
type User struct {
Age int`validate:"adult"`
}
func TestValidator(t *testing.T) {
// 注册自定义校验规则
validate := validator.New()
_ = validate.RegisterValidation("adult", func(fl validator.FieldLevel) bool {
return fl.Field().Int() >= 18
})
// 验证通过案例
user := User{Age: 10}
err := validate.Struct(user)
if err != nil {
fmt.Println(err)
}
}
运行后会输出:
Key: 'User.Age' Error:Field validation for 'Age' failed on the 'adult' tag
实现要点:
1.使用RegisterValidation
注册自定义校验标签
2.通过Field().Int()
获取字段值
3.返回布尔值表示校验结果
对于频繁创建/销毁的对象,使用sync.Pool
可以显著降低GC压力,提升性能。
JSON编码优化示例:
var bufferPool = sync.Pool{
New: func() interface{} { return new(bytes.Buffer) },
}
func EncodeJSON(v interface{}) ([]byte, error) {
buf := bufferPool.Get().(*bytes.Buffer)
defer bufferPool.Put(buf)
buf.Reset() // 关键:清空旧数据
err := json.NewEncoder(buf).Encode(v)
return buf.Bytes(), err
}
使用注意:
错误地在goroutine内部调用Add()会导致竞态条件:
// 危险用法
for i := 0; i < 10; i++ {
go func() {
wg.Add(1) // 并发写入导致竞态
defer wg.Done()
}()
}
正确做法:
// 安全用法
for i := 0; i < 10; i++ {
wg.Add(1) // 在goroutine外部提前Add
go func() {
defer wg.Done()
}()
}
wg.Wait()
关键原则:
1.Add()调用必须在goroutine外部
2.Done()与Add()次数严格匹配
3.Wait()要在所有Add()完成后调用
不同类型的nil表现
var (
p *int // nil pointer
s []int // nil slice
m map[int]int // nil map
f func() // nil function
i interface{} // nil interface
)
危险的nil比较
var p *int = nil
fmt.Println(p == nil) // true
fmt.Println(i == p) // false!
原理剖析:
(type, value)
二元组安全实践:
1.使用明确的类型断言检查
2.避免直接比较接口与具体类型指针
3.使用反射进行深度nil检查
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有