#go #reflection #types
#Вперед #отражение #типы
Вопрос:
У меня есть функция, которая возвращает анонимную структуру. Эта функция сгенерирована, и поэтому я не могу изменить код или создать тип для возвращаемого значения.
func foo() struct {
Prop int
} {
result := new(struct {
Prop int
})
result.Prop = 1
return *result
}
В других местах кодовой базы я хочу определить функцию, bar()
которая принимает в качестве аргумента возвращаемый тип foo()
func bar(arg ReturnTypeOfFoo) {
// ...
}
Могу ли я сделать это, не определяя ReturnTypeOfFoo
тип вручную? Есть ли какое-то отражение, которое я могу сделать foo()
?
Ответ №1:
Вы можете использовать ту же анонимную структуру, что и тип параметра для bar()
:
func bar(arg struct {
Prop int
}) {
fmt.Printf("Received: % vn", arg)
}
Тогда следующий допустимый код:
res := foo()
bar(res)
И выводит (попробуйте это на игровой площадке Go):
Received: {Prop:1}
Это возможно, потому что вызов bar(res)
допустим, если все аргументы могут быть присвоены типам параметров bar()
, а тип возвращаемого значения анонимной структуры foo()
может быть присвоен параметру анонимной структуры bar()
.
Если вам нужно, чтобы это было динамическим (например, тип результата foo()
может измениться при повторном создании), вы можете использовать go/parser
пакет для анализа сгенерированного источника и генерации bar()
с идентичным типом параметра, идиоматически выполняемого при go generate
запуске. Вы должны сделать эту часть процесса генерации, которая генерирует / изменяет foo
, поэтому foo
и bar
будет синхронизирована.
Комментарии:
1. Добавление шага 2-го поколения — отличная рекомендация. Спасибо!
Ответ №2:
Могу ли я сделать это, не определяя тип ReturnTypeOfFoo вручную?
Нет, потому что …
Есть ли какое-то отражение, которое я могу сделать с foo()?
Нет. Вы не можете использовать отражение во время компиляции.