github

https://github.com/dave/jennifer

Jennifer

Jennifer是Go的代码生成器。

  1. package main
  2. import (
  3. "fmt"
  4. . "github.com/dave/jennifer/jen"
  5. )
  6. func main() {
  7. f := NewFile("main")
  8. f.Func().Id("main").Params().Block(
  9. Qual("fmt", "Println").Call(Lit("Hello, world")),
  10. )
  11. fmt.Printf("%#v", f)
  12. }

输出:

  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("Hello, world")
  5. }

安装

  1. go get -u github.com/dave/jennifer/jen

例子

Jennifer有一套完整的示例——参见godoc的索引。下面是珍妮弗在现实生活中的一些例子:

  • genjen (which generates much of jennifer, using data in data.go)
  • zerogen
  • go-contentful-generator

    渲染

    对于测试,可以使用%#v动词用fmt包呈现文件或语句。
    1. c := Id("a").Call(Lit("b"))
    2. fmt.Printf("%#v", c)
    3. // Output:
    4. // a("b")
    不建议在生产环境中使用这种方法,因为任何错误都会导致panic。用于生产环境,File.RenderFile.Save 是被推荐的。

标识符

Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

Id

Id renders an identifier.

  1. c := If(Id("i").Op("==").Id("j")).Block(
  2. Return(Id("i")),
  3. )
  4. fmt.Printf("%#v", c)
  5. // Output:
  6. // if i == j {
  7. // return i
  8. // }

Dot

Dot 点呈现一个句点,后面跟着一个标识符。用于字段和选择器。

  1. c := Qual("a.b/c", "Foo").Call().Dot("Bar").Index(Lit(0)).Dot("Baz")
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // c.Foo().Bar[0].Baz

Qual

Qual 呈现一个限定标识符。

  1. c := Qual("encoding/gob", "NewEncoder").Call()
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // gob.NewEncoder()

当与文件一起使用时,会自动添加导入。如果路径匹配本地路径,包的名字是省略。如果包名称冲突,则会自动重命名它们。

  1. f := NewFilePath("a.b/c")
  2. f.Func().Id("init").Params().Block(
  3. Qual("a.b/c", "Foo").Call().Comment("Local package - name is omitted."),
  4. Qual("d.e/f", "Bar").Call().Comment("Import is automatically added."),
  5. Qual("g.h/f", "Baz").Call().Comment("Colliding package name is renamed."),
  6. )
  7. fmt.Printf("%#v", f)
  8. // Output:
  9. // package c
  10. //
  11. // import (
  12. // f "d.e/f"
  13. // f1 "g.h/f"
  14. // )
  15. //
  16. // func init() {
  17. // Foo() // Local package - name is omitted.
  18. // f.Bar() // Import is automatically added.
  19. // f1.Baz() // Colliding package name is renamed.
  20. // }

注意,给定任意包路径,不可能可靠地确定包名,因此从路径中猜测合理的名称并添加为别名。所有标准库包的名字是已知的这些不需要别名。如果需要对别名进行更多控制,请阅读 File.ImportNameFile.ImportAlias

List

list 呈现一个逗号分隔的列表。用于多个返回函数。

  1. c := List(Id("a"), Err()).Op(":=").Id("b").Call()
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a, err := b()

关键字

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

简单的关键字、预先声明的标识符和内置函数是自解释的:

Construct Name
Keywords Break, Chan, Const, Continue, Default, Defer, Else, Fallthrough, Func, Go, Goto, Range, Select, Type, Var
Functions Append, Cap, Close, Complex, Copy, Delete, Imag, Len, Make, New, Panic, Print, Println, Real, Recover
Types Bool, Byte, Complex64, Complex128, Error, Float32, Float64, Int, Int8, Int16, Int32, Int64, Rune, String, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr
Constants True, False, Iota, Nil
Helpers Err

内置函数接受参数列表并适当地呈现它们:

  1. c := Id("a").Op("=").Append(Id("a"), Id("b").Op("..."))
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a = append(a, b...)

下面解释了If, for, Interface, Struct, Switch, Case, Return和Map的特殊情况。

操作符

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

Op呈现提供的操作符/令牌。

  1. c := Id("a").Op(":=").Id("b").Call()
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a := b()
  1. c := Id("a").Op("=").Op("*").Id("b")
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a = *b
  1. c := Id("a").Call(Id("b").Op("..."))
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a(b...)
  1. c := If(Parens(Id("a").Op("||").Id("b")).Op("&&").Id("c")).Block()
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // if (a || b) && c {
  5. // }

花括号

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

几种方法呈现花括号,总结如下:

Name Prefix Separator Example
Block \n func a() { ... } or if a { ... }
Interface interface \n interface { ... }
Struct struct \n struct { ... }
Values , []int{1, 2} or A{B: "c"}

block 呈现一个用大括号括起来的语句列表。用于代码块。

  1. c := Func().Id("foo").Params().String().Block(
  2. Id("a").Op("=").Id("b"),
  3. Id("b").Op("++"),
  4. Return(Id("b")),
  5. )
  6. fmt.Printf("%#v", c)
  7. // Output:
  8. // func foo() string {
  9. // a = b
  10. // b++
  11. // return b
  12. // }
  1. c := If(Id("a").Op(">").Lit(10)).Block(
  2. Id("a").Op("=").Id("a").Op("/").Lit(2),
  3. )
  4. fmt.Printf("%#v", c)
  5. // Output:
  6. // if a > 10 {
  7. // a = a / 2
  8. // }

当直接在case或Default后面使用时,将应用一个特殊的case,其中省略了大括号。这允许在switch和select语句中使用。看到的例子。

接口, 结构体

Interface和struct 呈现关键字,后跟一个用大括号括起来的语句列表。

  1. c := Var().Id("a").Interface()
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // var a interface{}
  1. c := Type().Id("a").Interface(
  2. Id("b").Params().String(),
  3. )
  4. fmt.Printf("%#v", c)
  5. // Output:
  6. // type a interface {
  7. // b() string
  8. // }
  1. c := Id("c").Op(":=").Make(Chan().Struct())
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // c := make(chan struct{})
  1. c := Type().Id("foo").Struct(
  2. List(Id("x"), Id("y")).Int(),
  3. Id("u").Float32(),
  4. )
  5. fmt.Printf("%#v", c)
  6. // Output:
  7. // type foo struct {
  8. // x, y int
  9. // u float32
  10. // }

圆括号

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

输出括号的几种方法,总结如下:

Name Prefix Separator Example
Call , fmt.Println(b, c)
Params , func (a *A) Foo(i int) { ... }
Defs \n const ( ... )
Parens []byte(s) or a / (b + c)
Assert . s, ok := i.(string)

调用

call 呈现用括号括起来的逗号分隔的列表。用于函数调用。

  1. c := Qual("fmt", "Printf").Call(
  2. Lit("%#v: %T\n"),
  3. Id("a"),
  4. Id("b"),
  5. )
  6. fmt.Printf("%#v", c)
  7. // Output:
  8. // fmt.Printf("%#v: %T\n", a, b)

参数

Params呈现一个用圆括号括起来的逗号分隔的列表。用于函数参数和方法接收器。

  1. c := Func().Params(
  2. Id("a").Id("A"),
  3. ).Id("foo").Params(
  4. Id("b"),
  5. Id("c").String(),
  6. ).String().Block(
  7. Return(Id("b").Op("+").Id("c")),
  8. )
  9. fmt.Printf("%#v", c)
  10. // Output:
  11. // func (a A) foo(b, c string) string {
  12. // return b + c
  13. // }

定义多个

Defs 呈现一份声明列表包含在括号。用于定义列表。

  1. c := Const().Defs(
  2. Id("a").Op("=").Lit("a"),
  3. Id("b").Op("=").Lit("b"),
  4. )
  5. fmt.Printf("%#v", c)
  6. // Output:
  7. // const (
  8. // a = "a"
  9. // b = "b"
  10. // )

括弧

Parens 在括号中呈现单个项。用于类型转换或指定计算顺序。

  1. c := Id("b").Op(":=").Index().Byte().Parens(Id("s"))
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // b := []byte(s)
  1. c := Id("a").Op("/").Parens(Id("b").Op("+").Id("c"))
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a / (b + c)

断言

Assert 呈现一个句点,后跟一个用圆括号括起来的项。用于类型断言。

  1. c := List(Id("b"), Id("ok")).Op(":=").Id("a").Assert(Bool())
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // b, ok := a.(bool)

控制流程

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

If, For

If 和 For 呈现关键字,后跟一个分号分隔的列表。

  1. c := If(
  2. Err().Op(":=").Id("a").Call(),
  3. Err().Op("!=").Nil(),
  4. ).Block(
  5. Return(Err()),
  6. )
  7. fmt.Printf("%#v", c)
  8. // Output:
  9. // if err := a(); err != nil {
  10. // return err
  11. // }
  1. c := For(
  2. Id("i").Op(":=").Lit(0),
  3. Id("i").Op("<").Lit(10),
  4. Id("i").Op("++"),
  5. ).Block(
  6. Qual("fmt", "Println").Call(Id("i")),
  7. )
  8. fmt.Printf("%#v", c)
  9. // Output:
  10. // for i := 0; i < 10; i++ {
  11. // fmt.Println(i)
  12. // }

Switch, Select

Switch, Select,Case和Block用于构建switch或select语句:

  1. c := Switch(Id("value").Dot("Kind").Call()).Block(
  2. Case(Qual("reflect", "Float32"), Qual("reflect", "Float64")).Block(
  3. Return(Lit("float")),
  4. ),
  5. Case(Qual("reflect", "Bool")).Block(
  6. Return(Lit("bool")),
  7. ),
  8. Case(Qual("reflect", "Uintptr")).Block(
  9. Fallthrough(),
  10. ),
  11. Default().Block(
  12. Return(Lit("none")),
  13. ),
  14. )
  15. fmt.Printf("%#v", c)
  16. // Output:
  17. // switch value.Kind() {
  18. // case reflect.Float32, reflect.Float64:
  19. // return "float"
  20. // case reflect.Bool:
  21. // return "bool"
  22. // case reflect.Uintptr:
  23. // fallthrough
  24. // default:
  25. // return "none"
  26. // }

Return

Return 关键字后跟逗号分隔的列表。

  1. c := Return(Id("a"), Id("b"))
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // return a, b

集合

Map

Map 呈现关键字,后跟一个用方括号括起来的项。用于映射定义。

  1. c := Id("a").Op(":=").Map(String()).String().Values()
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a := map[string]string{}

Index

Index 呈现用方括号括起来的冒号分隔的列表。用于数组/片索引和定义。

  1. c := Var().Id("a").Index().String()
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // var a []string
  1. c := Id("a").Op(":=").Id("b").Index(Lit(0), Lit(1))
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a := b[0:1]
  1. c := Id("a").Op(":=").Id("b").Index(Lit(1), Empty())
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a := b[1:]

Values

Values 呈现用大括号括起来的逗号分隔的列表。用于切片或复合字面值。

  1. c := Index().String().Values(Lit("a"), Lit("b"))
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // []string{"a", "b"}

Dict呈现为键/值对。与映射或复合文字的值一起使用。

  1. c := Map(String()).String().Values(Dict{
  2. Lit("a"): Lit("b"),
  3. Lit("c"): Lit("d"),
  4. })
  5. fmt.Printf("%#v", c)
  6. // Output:
  7. // map[string]string{
  8. // "a": "b",
  9. // "c": "d",
  10. // }
  1. c := Op("&").Id("Person").Values(Dict{
  2. Id("Age"): Lit(1),
  3. Id("Name"): Lit("a"),
  4. })
  5. fmt.Printf("%#v", c)
  6. // Output:
  7. // &Person{
  8. // Age: 1,
  9. // Name: "a",
  10. // }

DictFunc执行一个func(Dict)来生成值。

  1. c := Id("a").Op(":=").Map(String()).String().Values(DictFunc(func(d Dict) {
  2. d[Lit("a")] = Lit("b")
  3. d[Lit("c")] = Lit("d")
  4. }))
  5. fmt.Printf("%#v", c)
  6. // Output:
  7. // a := map[string]string{
  8. // "a": "b",
  9. // "c": "d",
  10. // }

注意:项目是关键时候下令呈现,确保可重复的代码。

字面值

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

Lit

Lit 显示文字。Lit只支持内置类型(bool、string、int、complex128、float64、float32、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64、uintptr和complex64)。传递任何其他类型的信息都会引起恐慌。

  1. c := Id("a").Op(":=").Lit("a")
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a := "a"
  1. c := Id("a").Op(":=").Lit(1.5)
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a := 1.5

LitFunc 通过执行所提供的函数生成要呈现的值。

  1. c := Id("a").Op(":=").LitFunc(func() interface{} { return 1 + 1 })
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a := 2

对于默认的常量类型(bool, int, float64, string, complex128), Lit将呈现无类型常量。

Code Output
Lit(true) true
Lit(1) 1
Lit(1.0) 1.0
Lit("foo") "foo"
Lit(0 + 1i) (0 + 1i)

对于所有其他内置类型(float32、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64、uintptr、complex64), Lit也会渲染该类型。

Code Output
Lit(float32(1)) float32(1)
Lit(int16(1)) int16(1)
Lit(uint8(0x1)) uint8(0x1)
Lit(complex64(0 + 1i)) complex64(0 + 1i)

内置的别名类型字节和符文需要一个特殊的情况。LitRune和LitByte呈现rune和字节文字。

Code Output
LitRune('x') 'x'
LitByte(byte(0x1)) byte(0x1)

注释

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

Comment

添加了一个注释。如果提供的字符串包含换行符,则注释将以多行格式格式化。

  1. f := NewFile("a")
  2. f.Comment("Foo returns the string \"foo\"")
  3. f.Func().Id("Foo").Params().String().Block(
  4. Return(Lit("foo")).Comment("return the string foo"),
  5. )
  6. fmt.Printf("%#v", f)
  7. // Output:
  8. // package a
  9. //
  10. // // Foo returns the string "foo"
  11. // func Foo() string {
  12. // return "foo" // return the string foo
  13. // }
  1. c := Comment("a\nb")
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // /*
  5. // a
  6. // b
  7. // */

如果注释字符串以”//“或”/*”开头,自动格式化将被禁用,字符串将被直接呈现。

  1. c := Id("foo").Call(Comment("/* inline */")).Comment("//no-space")
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // foo( /* inline */ ) //no-space

Commentf

使用格式字符串和参数列表添加注释。

  1. name := "foo"
  2. val := "bar"
  3. c := Id(name).Op(":=").Lit(val).Commentf("%s is the string \"%s\"", name, val)
  4. fmt.Printf("%#v", c)
  5. // Output:
  6. // foo := "bar" // foo is the string "bar"

Helpers

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

Func methods

所有接受可变项列表的构造都与接受func(*Group)的GroupFunc函数配对。用于嵌入逻辑。

  1. c := Id("numbers").Op(":=").Index().Int().ValuesFunc(func(g *Group) {
  2. for i := 0; i <= 5; i++ {
  3. g.Lit(i)
  4. }
  5. })
  6. fmt.Printf("%#v", c)
  7. // Output:
  8. // numbers := []int{0, 1, 2, 3, 4, 5}
  1. increment := true
  2. name := "a"
  3. c := Func().Id("a").Params().BlockFunc(func(g *Group) {
  4. g.Id(name).Op("=").Lit(1)
  5. if increment {
  6. g.Id(name).Op("++")
  7. } else {
  8. g.Id(name).Op("--")
  9. }
  10. })
  11. fmt.Printf("%#v", c)
  12. // Output:
  13. // func a() {
  14. // a = 1
  15. // a++
  16. // }

Add

Add将提供的项追加到语句中。

  1. ptr := Op("*")
  2. c := Id("a").Op("=").Add(ptr).Id("b")
  3. fmt.Printf("%#v", c)
  4. // Output:
  5. // a = *b
  1. a := Id("a")
  2. i := Int()
  3. c := Var().Add(a, i)
  4. fmt.Printf("%#v", c)
  5. // Output:
  6. // var a int

Do

Do将语句作为参数调用所提供的函数。用于嵌入逻辑。

  1. f := func(name string, isMap bool) *Statement {
  2. return Id(name).Op(":=").Do(func(s *Statement) {
  3. if isMap {
  4. s.Map(String()).String()
  5. } else {
  6. s.Index().String()
  7. }
  8. }).Values()
  9. }
  10. fmt.Printf("%#v\n%#v", f("a", true), f("b", false))
  11. // Output:
  12. // a := map[string]string{}
  13. // b := []string{}

Misc

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File

Tag

标记呈现一个结构标记

  1. c := Type().Id("foo").Struct(
  2. Id("A").String().Tag(map[string]string{"json": "a"}),
  3. Id("B").Int().Tag(map[string]string{"json": "b", "bar": "baz"}),
  4. )
  5. fmt.Printf("%#v", c)
  6. // Output:
  7. // type foo struct {
  8. // A string `json:"a"`
  9. // B int `bar:"baz" json:"b"`
  10. // }

注意:这些项在呈现时按键排序,以确保代码可重复。

Null

添加一个空项。空项在列表中不呈现任何内容,并且后面没有分隔符。
在列表中,nil也会产生同样的效果。

  1. c := Func().Id("foo").Params(
  2. nil,
  3. Id("s").String(),
  4. Null(),
  5. Id("i").Int(),
  6. ).Block()
  7. fmt.Printf("%#v", c)
  8. // Output:
  9. // func foo(s string, i int) {}

Empty

Empty添加一个空项。空项不呈现任何内容,只是在列表中后跟一个分隔符。

  1. c := Id("a").Op(":=").Id("b").Index(Lit(1), Empty())
  2. fmt.Printf("%#v", c)
  3. // Output:
  4. // a := b[1:]

Line

插入一个空行。

Clone

在传递*语句时要小心。考虑以下…

  1. a := Id("a")
  2. c := Block(
  3. a.Call(),
  4. a.Call(),
  5. )
  6. fmt.Printf("%#v", c)
  7. // Output:
  8. // {
  9. // a()()
  10. // a()()
  11. // }

Id(“a”)返回一个*语句,Call()方法将该语句追加两次。为了避免这种情况,可以使用克隆。Clone复制该语句,因此可以追加更多的令牌,而不会影响原始的令牌。

  1. a := Id("a")
  2. c := Block(
  3. a.Clone().Call(),
  4. a.Clone().Call(),
  5. )
  6. fmt.Printf("%#v", c)
  7. // Output:
  8. // {
  9. // a()
  10. // a()
  11. // }

Cgo

cgo“C”伪包是一种特殊的情况,总是没有包别名呈现。可以使用Qual、Anon或提供序言来添加导入。在文件中添加序言。与注释具有相同语义的CgoPreamble。如果提供了序言,则导入将被分隔,并且在其前面有序言。

  1. f := NewFile("a")
  2. f.CgoPreamble(`#include <stdio.h>
  3. #include <stdlib.h>
  4. void myprint(char* s) {
  5. printf("%s\n", s);
  6. }
  7. `)
  8. f.Func().Id("init").Params().Block(
  9. Id("cs").Op(":=").Qual("C", "CString").Call(Lit("Hello from stdio\n")),
  10. Qual("C", "myprint").Call(Id("cs")),
  11. Qual("C", "free").Call(Qual("unsafe", "Pointer").Parens(Id("cs"))),
  12. )
  13. fmt.Printf("%#v", f)
  14. // Output:
  15. // package a
  16. //
  17. // import "unsafe"
  18. //
  19. // /*
  20. // #include <stdio.h>
  21. // #include <stdlib.h>
  22. //
  23. // void myprint(char* s) {
  24. // printf("%s\n", s);
  25. // }
  26. // */
  27. // import "C"
  28. //
  29. // func init() {
  30. // cs := C.CString("Hello from stdio\n")
  31. // C.myprint(cs)
  32. // C.free(unsafe.Pointer(cs))
  33. // }

File

Identifiers Keywords Operators Braces Parentheses Control flow Collections Literals Comments Helpers Misc File
**
表示单个源文件。包导入是根据文件自动管理的。

NewFile

用指定的包名创建一个新文件。

NewFilePath

NewFilePath在指定包路径时创建一个新文件—包名从路径推断。

NewFilePathName

用指定的包路径和名称创建一个新文件。

  1. f := NewFilePathName("a.b/c", "main")
  2. f.Func().Id("main").Params().Block(
  3. Qual("a.b/c", "Foo").Call(),
  4. )
  5. fmt.Printf("%#v", f)
  6. // Output:
  7. // package main
  8. //
  9. // func main() {
  10. // Foo()
  11. // }

Save

保存呈现文件并保存到提供的文件名。

Render

Render将文件呈现给所提供的写入器。

  1. f := NewFile("a")
  2. f.Func().Id("main").Params().Block()
  3. buf := &bytes.Buffer{}
  4. err := f.Render(buf)
  5. if err != nil {
  6. fmt.Println(err.Error())
  7. } else {
  8. fmt.Println(buf.String())
  9. }
  10. // Output:
  11. // package a
  12. //
  13. // func main() {}

Anon

Anon添加了一个匿名导入。

  1. f := NewFile("c")
  2. f.Anon("a")
  3. f.Func().Id("init").Params().Block()
  4. fmt.Printf("%#v", f)
  5. // Output:
  6. // package c
  7. //
  8. // import _ "a"
  9. //
  10. // func init() {}

ImportName

ImportName提供路径的包名。如果指定,别名将从导入块中省略。这是可选的。如果未指定,则根据路径使用合理的包名,并将其作为别名添加到导入块中。

  1. f := NewFile("main")
  2. // package a should use name "a"
  3. f.ImportName("github.com/foo/a", "a")
  4. // package b is not used in the code so will not be included
  5. f.ImportName("github.com/foo/b", "b")
  6. f.Func().Id("main").Params().Block(
  7. Qual("github.com/foo/a", "A").Call(),
  8. )
  9. fmt.Printf("%#v", f)
  10. // Output:
  11. // package main
  12. //
  13. // import "github.com/foo/a"
  14. //
  15. // func main() {
  16. // a.A()
  17. // }

ImportNames

ImportNames允许多个名称作为映射导入。使用gennames命令自动生成一个go文件,该文件包含选择的包名的映射。

ImportAlias

ImportAlias提供了应该在导入块中使用的包路径的别名。可以使用句点强制点导入。

  1. f := NewFile("main")
  2. // package a should be aliased to "b"
  3. f.ImportAlias("github.com/foo/a", "b")
  4. // package c is not used in the code so will not be included
  5. f.ImportAlias("github.com/foo/c", "c")
  6. f.Func().Id("main").Params().Block(
  7. Qual("github.com/foo/a", "A").Call(),
  8. )
  9. fmt.Printf("%#v", f)
  10. // Output:
  11. // package main
  12. //
  13. // import b "github.com/foo/a"
  14. //
  15. // func main() {
  16. // b.A()
  17. // }

Comments

PackageComment在文件的顶部package关键字的上方添加一个注释。
HeaderComment将注释添加到文件的顶部,任何包注释的上方。在头注释下面呈现一个空行,以确保头注释不包含在包文档中。
CanonicalPath将规范导入路径注释添加到包子句中。

  1. f := NewFile("c")
  2. f.CanonicalPath = "d.e/f"
  3. f.HeaderComment("Code generated by...")
  4. f.PackageComment("Package c implements...")
  5. f.Func().Id("init").Params().Block()
  6. fmt.Printf("%#v", f)
  7. // Output:
  8. // // Code generated by...
  9. //
  10. // // Package c implements...
  11. // package c // import "d.e/f"
  12. //
  13. // func init() {}

CgoPreamble添加了一个cgo序言注释,直接呈现在“C”伪包导入之前。

PackagePrefix

如果你担心包生成别名冲突与局部变量的名字,你可以在这里设置一个前缀。包foo变成了{prefix}_foo。

  1. f := NewFile("a")
  2. f.PackagePrefix = "pkg"
  3. f.Func().Id("main").Params().Block(
  4. Qual("b.c/d", "E").Call(),
  5. )
  6. fmt.Printf("%#v", f)
  7. // Output:
  8. // package a
  9. //
  10. // import pkg_d "b.c/d"
  11. //
  12. // func main() {
  13. // pkg_d.E()
  14. // }