GO 编程模式学习笔记——GO GENERATION

本文介绍了Go语言中代码生成技术的应用,特别是如何通过模板解决泛型问题,提升代码可读性和性能。讨论了使用gogenerate和第三方工具如genny进行代码自动生成的方法,以及模板和脚本在实际项目中的运用案例。
摘要由CSDN通过智能技术生成

GO编程模式学习笔记系列为学习陈皓的GO编程模式系列文章记录与心得。
原文链接:GO 编程模式:GO GENERATION

Go语言代码生成主要还是用来解决编程泛型的问题。Go语言的类型检查有两种技术,一种是 Type Assert,一种是Reflection。

反射实现一个支持任何类型的slice(但是必须是同一类型,这也符合范型定义)

type Container struct {
    s reflect.Value
}
func NewContainer(t reflect.Type, size int) *Container {
    if size <=0  { size=64 }
    return &Container{
        s: reflect.MakeSlice(reflect.SliceOf(t), 0, size), 
    }
}
func (c *Container) Put(val interface{})  error {
    if reflect.ValueOf(val).Type() != c.s.Type().Elem() {
        return fmt.Errorf(“Put: cannot put a %T into a slice of %s", 
            val, c.s.Type().Elem()))
    }
    c.s = reflect.Append(c.s, reflect.ValueOf(val))
    return nil
}
func (c *Container) Get(refval interface{}) error {
    if reflect.ValueOf(refval).Kind() != reflect.Ptr ||
        reflect.ValueOf(refval).Elem().Type() != c.s.Type().Elem() {
        return fmt.Errorf("Get: needs *%s but got %T", c.s.Type().Elem(), refval)
    }
    reflect.ValueOf(refval).Elem().Set( c.s.Index(0) )
    c.s = c.s.Slice(1, c.s.Len())
    return nil
}

代码生成

上述代码可读性稍微有点差,性能较差。如何改进呢?
这样的问题在C++中是通过模板来解决,但是模版就是生成对应代码。只不过是C++的编译器帮你做了这件事,Go语言编译器没有做。在Go实现范型之前,可以自己动手。

要玩 Go的代码生成,你需要三件事:

  • 一个函数模板,其中设置好相应的占位符。
  • 一个脚本,用于按规则来替换文本并生成新的代码。
  • 一行注释代码

go generate 命令本身支持代码生成在,写好模板和替换脚本,在使用的时候加一行注释即可

//go:generate ./gen.sh ./template/filter.tmp.go gen Employee filter
func filterEmployeeExample() {
    ...

更进一步,有第三方工具可以生成代码:

https://github.com/cheekybits/genny/blob/master/parse/test/slice/ensure_slice_test.go

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值