Я обнаруживаю генератор (go generate), и я пытаюсь сгенерировать функцию проверки для своей структуры.
Идея состоит в том, что я не хочу, чтобы моя программа использовала отражение во время выполнения, я бы предпочел, чтобы генератор использовал отражение, чтобы сгенерировать фактический метод, который я хочу использовать.
проблема в том, что я не могу импортировать свои структуры в код генератора, единственный способ, который я нашел до сих пор, - это прочитать файл .go из генератора и вручную проанализировать типы, определенные там, с помощью регулярного выражения
У меня есть что-то вроде
models / models.go:
package models
//go:generate go run ../generator.go -file models.go
type MyStruct struct {
...
}
generator.go:
package main
func main() {
f, err := ioutil.ReadFile(fileName) // I read filename from the flag provided
...
// I parse f to generate my stuff
}
Я бы очень предпочел иметь пакет интроспекции, который будет принимать код go в виде строки и давать мне некоторую информацию о структуре, определенной там.
Или, может быть, есть способ импортировать файл, который вызывает go: generate, чтобы получить прямой доступ к типам
Я бы рекомендовал пакет astgolang.org/pkg/go/ast
Я не знал об этой упаковке, похоже, это именно то, что я ищу, спасибо
Отражение по определению предназначено для среды выполнения, а не для анализа исходного кода.
предпочитаю использовать go / loader и go / types to go / ast. go / ast - низкий уровень.

Имя файла указывать не нужно, этот код делает то же самое:
//go:generate go run ../generator.go -file $GOFILE
С помощью пакета text / template вам не нужно разбирать файл. Очень простой пример будет примерно таким. Это даст вам ключ к разгадке:
package main
import (
"flag"
"os"
"text/template"
)
//go:generate go run main.go -name=A
//go:generate go run main.go -name=B
//go:generate go run main.go -name=C
var name = flag.String("name", "test", "name of struct")
var code = `
package main
type Struct{{.}} struct {}
func (s *Struct{{.}} ) Vailadte() bool {
return true
}
`
func main() {
flag.Parse()
file, _ := os.Create(*name + ".go")
defer file.Close()
tmpl, _ := template.New("test").Parse(code)
tmpl.Execute(file, *name)
}
Спасибо, использование $ GOFILE - это хорошо, хотя использование шаблона не решает мою проблему, это поможет сгенерировать выходной код, но мне все равно нужно получить объекты из исходного файла
Вы уже смотрели пакеты
go/parser,go/astиgo/token? Вы можете прочитать файл, разметить код и использовать его для генерации кода. Существует множество примеров пакетов, делающих это. Например, на ум приходит собственный mockgen от Google.