Могу ли я присвоить псевдоним возвращаемому типу функции

#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()?

Нет. Вы не можете использовать отражение во время компиляции.