[golang]自動生成範式(模板)程式

 在 Golang 中,自動生成範式(模板)程式的方式有幾種,取決於你的需求,例如:

  • 使用 go generate(標準方式)
  • 使用 text/templatehtml/template(基於模板的生成)
  • 使用 go:embed(嵌入模板文件)
  • 使用代碼生成工具(如 stringergomockent 等)
  • 使用 AI/LLM 工具(生成重複性較高的程式碼)

1. 使用 go generate 自動生成程式碼

go generate 是 Go 內建的生成工具,允許在程式中自動執行命令來生成代碼。

範例:生成 Getter 方法

假設我們有一個 Person 結構體,我們想自動生成 GetName()GetAge() 方法。

步驟 1:建立 person.go

//go:generate go run gen_person.go
package main type Person struct { Name string Age int }

步驟 2:建立 gen_person.go 來生成程式碼

package main
import ( "fmt" "os" ) func main() { code := `package main func (p *Person) GetName() string { return p.Name } func (p *Person) GetAge() int { return p.Age } ` err := os.WriteFile("person_gen.go", []byte(code), 0644) if err != nil { fmt.Println("Error writing file:", err) } }

步驟 3:執行 go generate

go generate ./...

執行後,會生成 person_gen.go,內容如下:

package main
func (p *Person) GetName() string { return p.Name } func (p *Person) GetAge() int { return p.Age }

這種方式適用於自動生成簡單的 getter/setter 或其他重複性代碼。


2. 使用 text/template 生成程式碼

Go 提供 text/templatehtml/template,可以用來生成程式碼。

範例:使用模板生成 CRUD 代碼

package main
import ( "os" "text/template" ) const tmpl = `package main type {{.StructName}} struct { {{range .Fields}} {{.Name}} {{.Type}} {{end}} } func New{{.StructName}}() *{{.StructName}} { return &{{.StructName}}{} } ` type Field struct { Name string Type string } type TemplateData struct { StructName string Fields []Field } func main() { data := TemplateData{ StructName: "User", Fields: []Field{ {"ID", "int"}, {"Name", "string"}, {"Email", "string"}, }, } t := template.Must(template.New("struct").Parse(tmpl)) file, _ := os.Create("user_gen.go") defer file.Close() t.Execute(file, data) }

執行:

go run main.go

生成 user_gen.go

package main
type User struct { ID int Name string Email string } func NewUser() *User { return &User{} }

這種方式適用於自動生成結構體、API 處理函數等。


3. 使用 go:embed 讀取模板文件

如果你的模板存放在文件中,可以用 go:embed 來讀取。

範例:從外部模板生成代碼

建立 template.txt

package main
type {{.StructName}} struct { {{range .Fields}} {{.Name}} {{.Type}} {{end}} }

Go 代碼:

package main
import ( _ "embed" "os" "text/template" ) //go:embed template.txt var tmpl string type Field struct { Name string Type string } type TemplateData struct { StructName string Fields []Field } func main() { data := TemplateData{ StructName: "Product", Fields: []Field{ {"ID", "int"}, {"Name", "string"}, {"Price", "float64"}, }, } t := template.Must(template.New("struct").Parse(tmpl)) file, _ := os.Create("product_gen.go") defer file.Close() t.Execute(file, data) }

這樣,模板可以外部管理,方便調整。


4. 使用 stringer 自動生成字串方法

stringer 是 Go 官方工具,可為 const 生成 String() 方法。

範例:自動生成 String() 方法

建立 color.go

//go:generate stringer -type=Color
package main type Color int const ( Red Color = iota Green Blue )

執行:

go generate

生成 color_string.go

package main
import "strconv" func (c Color) String() string { switch c { case Red: return "Red" case Green: return "Green" case Blue: return "Blue" default: return "Color(" + strconv.Itoa(int(c)) + ")" } }

這對於 enum 類型很有用。


5. 使用 gomock 生成測試 Mock

如果你使用 gomock 來測試,可以自動生成 mock 類:

go install go.uber.org/mock/mockgen@latest
mockgen -source=user_service.go -destination=mocks/mock_user_service.go -package=mocks

這樣可以自動生成 Mock 類,減少手動編寫的工作。


結論

方法適用場景
go generate任何基於 Go 程式自動生成的代碼
text/template根據模板生成結構體、CRUD 代碼
go:embed讀取外部模板,提高靈活性
stringer自動生成 String() 方法
gomock生成測試用 mock

如果你是要自動生成 API、資料庫 CRUDRPC 服務,可以考慮 ent ORMprotobuf 等工具。

留言

這個網誌中的熱門文章

[Kotlin]如何學習Kotlin

[golang]如何使用 gorm 高效執行批量插入 (可以透過 Create()、CreateInBatches(),或者 原生 SQL 語句 來提升效率)

[Kotlin]Kotlin Multiplatform (KMP) 如何安裝使用和部署