Отражение типа структуры при чтении файла .go

Я обнаруживаю генератор (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, чтобы получить прямой доступ к типам

Вы уже смотрели пакеты go/parser, go/ast и go/token? Вы можете прочитать файл, разметить код и использовать его для генерации кода. Существует множество примеров пакетов, делающих это. Например, на ум приходит собственный mockgen от Google.

Elias Van Ootegem 14.12.2018 16:55

Я бы рекомендовал пакет astgolang.org/pkg/go/ast

ssemilla 14.12.2018 16:56

Я не знал об этой упаковке, похоже, это именно то, что я ищу, спасибо

BlueMagma 14.12.2018 16:58

Отражение по определению предназначено для среды выполнения, а не для анализа исходного кода.

Adrian 14.12.2018 17:24

предпочитаю использовать go / loader и go / types to go / ast. go / ast - низкий уровень.

mh-cbon 14.12.2018 20:05
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
3
5
1 142
1

Ответы 1

Имя файла указывать не нужно, этот код делает то же самое:

//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 - это хорошо, хотя использование шаблона не решает мою проблему, это поможет сгенерировать выходной код, но мне все равно нужно получить объекты из исходного файла

BlueMagma 17.12.2018 11:11

Другие вопросы по теме