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

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

Validator自定义校验规则

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优化对象复用

对于频繁创建/销毁的对象,使用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
}

使用注意

  • 取出对象后必须调用Reset()
  • 对象生命周期不受池管理
  • 适合重量级对象的复用

sync.WaitGroup的正确使用

错误地在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外部提前Addgo func() {defer wg.Done()}()
}
wg.Wait()

关键原则

1.Add()调用必须在goroutine外部

2.Done()与Add()次数严格匹配

3.Wait()要在所有Add()完成后调用

nil的语义陷阱

不同类型的nil表现

var (p *int          // nil pointers []int         // nil slicem map[int]int   // nil mapf func()        // nil functioni interface{}   // nil interface
)

危险的nil比较

var p *int = nil
fmt.Println(p == nil)    // true
fmt.Println(i == p)      // false!

原理剖析

  • 接口变量包含(type, value)二元组
  • 当存储nil指针时,类型信息仍然存在
  • 与纯nil接口比较时会返回false

安全实践

1.使用明确的类型断言检查

2.避免直接比较接口与具体类型指针

3.使用反射进行深度nil检查

相关文章:

  • Flutter - UIKit开发相关指南 - 导航
  • 互联网大厂Java求职面试:电商商品推荐系统中的AI技术应用
  • 第31讲 循环缓冲区与命令解析
  • 【Tools】omnetpp5.6.2安装
  • 理解 Token 索引 vs 字符位置
  • DAY 17 训练
  • 【CTF】Linux Shell RCE绕过(bypass)技术总结
  • 低代码开发:开启软件开发的新篇章
  • 算法导论第9章思考题
  • 【c++】【数据结构】二叉搜索树详解
  • 数码管模块
  • 【Linux篇】高并发编程终极指南:线程池优化、单例模式陷阱与死锁避坑实战
  • M. Moving Both Hands(反向图+Dijkstra)
  • 蓝桥杯14届国赛 合并数列
  • Spyglass:在batch/shell模式下运行目标的顶层是什么?
  • 【project】--数据挖掘
  • Docker 部署 - Crawl4AI 文档 (v0.5.x)
  • 【TI MSPM0】CCS工程管理
  • 【LwIP源码学习6】UDP部分源码分析
  • 研修室智慧化升级实践:线上预约+智能门锁的融合方案
  • 受美关税影响,本田预计新财年净利下降七成,并推迟加拿大建厂计划
  • 成都警方通报:8岁男孩落水父母下水施救,父亲遇难
  • “救护车”半路加价?陕西卫健委已介入,记者调查:黑救护车挤占市场
  • A股高开高走:沪指涨0.82%,创指涨2.63%,超4100股收涨
  • 湛江霞山通报渔船火灾:起火船舶共8艘,无人员伤亡或被困
  • 汉斯·季默:不会指挥的声音工程师终成音乐“大神”