任何惯用的 generate/preprocessing 解决方案库?

Any idiomatic generate/preprocessing solution library?

我真的很喜欢 Go,但让我对 if-err 地狱以及当我在 Go 代码中与其他语言同步数据类型时感到疯狂。对于 C/C++ 我可以很容易地用宏来处理这些东西,而 Go 开发人员说 Go 的惯用解决方案是代码生成,但我没有找到任何开箱即用的解决方案。

基本上,我需要的是

  1. 阅读源代码,检查每种类型的用法是否在特殊配置文件中列出。如果是,则将其更改为配置中的那个。
  2. 阅读源代码,检查每个函数是否在配置文件中列出。如果是,则使用模板配置中的代码片段更改它,如果缺少则添加必要的导入。
  3. 可能,添加一些基于 return 值的多态性以防止类型转换。
  4. 也许,添加(err error)逻辑。不确定这是个好主意。

像这样

code.go

func getConn(id platform.UUID) (res1 string, res2 platform.res) {
  res1 = driver_native_res(id)
  res2 = driver_native_res(id)
  return
}

代码-gen.go

import (
  "linux"
)
func getConn(id uint64) (res1 string, res2 int32, err error) {
  res1, err = linux.GetResAsString(id)
  if err != nil {
    return
  }
  res2, err = linux.GetRes(id)
  if err != nil {
    return
  }
  return
}

我知道 go AST,但用它实现这些功能似乎不是很快。我希望有一些更简单的解决方案。

如您所见,没有宏,而且不太可能。在某些时候可能会有泛型,这可能会有所帮助。同时,有几个代码生成选项。您可以为此使用 go generate:

// add a magic comment to your go file 
// which needs some extra generated code
// this calls a tool called stringer to generate, 
// but it could be yacc or some homemade tool. 
//go:generate stringer -type=Pill

// call go generate to generate the methods:
go generate

https://blog.golang.org/generate

但这确实需要你有一个工具来生成你想要的代码,比如stringer。

或者您可以只使用 text/template,构建您自己的模板,然后 运行 一个简单的工具将值替换到该模板中(来自配置文件,或者可能是命令行上的参数) .

mytool generate -type=thing -field=type...
... mytool loads a tmplate file, 
runs it through text/template and outputs it. 

这非常简单,您可以使用它轻松构建自定义系统,但您可能希望生成一次,然后使用代码。以下是这种方法的一些示例:

http://clipperhouse.github.io/gen/

https://github.com/fragmenta/fragmenta

最后,您可以使用 grpc 等工具生成多种语言的结构,以简化跨语言通信,这听起来正是您正在寻找的用例:

https://grpc.io/docs/quickstart/go.html

我会先看看 grpc 之类的东西。