TL; DR:コードジェネレーター。
Postgresql、Scylla、JSONなどのさまざまなストレージドライバをサポートするライブラリを開発していると想像してください。
これらの各ドライバーには、他のライブラリへの外部依存関係があります。Postgresql-データベース/sql、github.com / lib / pq。Scylla-github.com/scylladb/gocqlまたは標準のgithub.com/gocql/gocql。JSON-github.com/mailru/easyjsonまたはgithub.com/json-iterator/go、またはencoding / json。
.
, : Postgres , , .
, .
, . : sql.go, cql.go, json.go.
, .
pkger .
pkger —
files := make([]string, 0)
if *cql {
files = append(files, pkger.Include("/cql.go"))
}
if *json {
files = append(files, pkger.Include("/json.go"))
}
if *sql {
files = append(files, pkger.Include("/sql.go"))
}
pkger -o < >
, .
go generate
//go:generate pkger -o < >
, .
— Go, .
for i := range files {
_, filename := filepath.Split(files[i])
in, err := pkger.Open(files[i])
if err != nil {
panic(err)
}
src := []byte(fmt.Sprintf(genStr, strings.Join(os.Args[1:], " ")))
reader := bufio.NewReader(in)
for {
line, err := reader.ReadBytes('\n')
if strings.HasPrefix(string(line), "package ") {
line = []byte(fmt.Sprintf("package %s\n", *pkgName))
}
src = append(src, line...)
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
}
if err := ioutil.WriteFile(filename, src, 0644); err != nil {
panic(err)
}
in.Close()
}
“cmd/< >”. , .
go get github.com/< >/< >/< >
そして、彼のプロジェクトでコードジェネレーターを起動します
< > -sql
ライブラリを更新する必要がある場合-ユーザーがコードジェネレータを更新します
go get -u github.com/< >/< >/< >
そして、それは再び世代を開始します。
依存関係を使用するこのアプローチの例は、Iと クレーカーnanライブラリに実装されています。通常モード、インポート、およびコード生成バージョンの両方でライブラリを操作できます。