任何惯用的生成/预处理解决方案库?

时间:2017-08-10 19:47:28

标签: go metaprogramming code-generation

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

所以基本上,我需要的是像

  1. 阅读源代码,了解每种类型用法检查是否列在特殊配置文件中。如果是,则使用config中的那个进行更改。
  2. 读取源代码,检查每个函数是否在配置文件中列出。如果是,请使用模板中的代码段更改它,如果它丢失则添加必要的导入。
  3. 可能会根据返回值添加一些多态,以防止类型转换。
  4. 也许,添加(err error)逻辑。不确定这是个好主意。
  5. 喜欢这个

    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
    }
    

    我知道去AST,但似乎用它来实现这些功能并不是很快。我希望有一些更容易的解决方案。

1 个答案:

答案 0 :(得分:0)

正如您所发现的,没有宏,也不太可能。在某些时候可能会有一些可能有用的泛型。与此同时,代码生成有几个选项。您可以使用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。

或者您可以使用文本/模板,构建自己的模板,并运行一个简单的工具,将值替换为此模板(来自配置文件,或者可能是命令行中的参数)。

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这样的东西。