Goption:一个针对 Go struct 的代码生成器


缘起

写代码里有个绕不开的话题就是如何写构造函数

  • Java 里有 JavaBean 作为标准,空构造参数 + 自定义的 setter
  • C++ 里靠重载实现任意场景的构造
  • Python 里可以可以支持传你需要的参数

Go 呢,一无所有,最通行的办法,大概是可变参作为可选的 options

func NewX(options ...Option) *X {
	x := &X{}
	for _, opt := range options {
		opt.apply(x)
	}
	return x
}

但是,你每次不得不把一个个简单的参数定义成一大堆的 option,多么烦人。

所以,goption 就出场了

一睹为快

是不是太快了看不清。听我慢慢道来。

以 Goland 为示例,首先在定义 struct 时添加标识

//go:generate goption -p . -c Person -w
type Person struct{
	// your person fields
}

这样的好处是,IDE 可以为你提供快捷按钮,你只需要点一下就生成了。

点击按钮后,会在同 packagge 下生成 person_option_gen.go 代码大约是这个样子:

type PersonOption func(*Person)

func NewPerson(opts ...PersonOption) (person *Person) {
	person = &Person{}
	for _, opt := range opts {
		opt(person)
	}
	return
}

func WithPersonName(name string) func(*Person) {
	return func(person *Person) {
		person.Name = name
	}
}

// ...

如何使用呢,也很简单:

func main() {
	p1 := NewPerson()		// 普通构造方式

	p2 := NewPerson(		// 自定义字段方式
		WithPersonName(`zhangsan`),
		WithPersonAge(18),
	)
	println(p1, p2)
}

使用起来真是爽了不少。

放上代码地址:https://github.com/micln/goption

如何实现

最开始绕了点弯路,自己一层层解析 ast.Node,后来发现 go/doc 已经帮你解析了 package,里面有哪些 Types,哪些 Funcs,都非常清楚,可以直接拿来用。

唯一需要处理的就是如何 ast.Expr 表示的代码展示出来,好在之前玩过 ast 相关的,也整理了一下 astutil 放了出来,后面还会继续完善。所以就大大减少了难度。

后续

费这么大劲如果只做这一件事确实有点亏,后续希望把 Generator 开放出来,我帮你解析源码和集成 IDE,你只需要自定义模板,就可以生成任何你想要的辅助方法。

Avatar
huiren
Code Artisan

问渠那得清如许,为有源头活水来

相关

下一页
上一页
comments powered by Disqus