1 回答

TA貢獻1847條經驗 獲得超11個贊
reflect.Type.String()
僅返回類型名稱,因此如果函數值具有命名類型,您只會看到類型名稱。請注意,如果函數值是函數文字(具有未命名類型),這將打印函數的簽名:
var?myFunc?ModuleInitFunc fmt.Printf("%T\n",?myFunc) fmt.Printf("%T\n",?func(i?int)?error?{?return?nil?})
輸出(在Go Playground上嘗試):
main.ModuleInitFunc func(int)?error
如果該類型是命名類型,我們必須自己構造簽名,但幸運的是,它reflect.Type
擁有我們需要的所有信息。
Type.In()
返回第i個參數的類型,同理返回第i個Type.Out()
結果類型的類型。
使用這些,這是一個返回函數值簽名的示例實現:
func signature(f interface{}) string {
? ? t := reflect.TypeOf(f)
? ? if t.Kind() != reflect.Func {
? ? ? ? return "<not a function>"
? ? }
? ? buf := strings.Builder{}
? ? buf.WriteString("func (")
? ? for i := 0; i < t.NumIn(); i++ {
? ? ? ? if i > 0 {
? ? ? ? ? ? buf.WriteString(", ")
? ? ? ? }
? ? ? ? buf.WriteString(t.In(i).String())
? ? }
? ? buf.WriteString(")")
? ? if numOut := t.NumOut(); numOut > 0 {
? ? ? ? if numOut > 1 {
? ? ? ? ? ? buf.WriteString(" (")
? ? ? ? } else {
? ? ? ? ? ? buf.WriteString(" ")
? ? ? ? }
? ? ? ? for i := 0; i < t.NumOut(); i++ {
? ? ? ? ? ? if i > 0 {
? ? ? ? ? ? ? ? buf.WriteString(", ")
? ? ? ? ? ? }
? ? ? ? ? ? buf.WriteString(t.Out(i).String())
? ? ? ? }
? ? ? ? if numOut > 1 {
? ? ? ? ? ? buf.WriteString(")")
? ? ? ? }
? ? }
? ? return buf.String()
}
測試它:
var myFunc ModuleInitFunc
fmt.Println(signature(func(i int) error { return nil }))
fmt.Println(signature(myFunc))
fmt.Println(signature(time.Now))
fmt.Println(signature(os.Open))
fmt.Println(signature(log.New))
fmt.Println(signature(""))
輸出(在Go Playground上嘗試):
func (int) error
func (int) error
func () time.Time
func (string) (*os.File, error)
func (io.Writer, string, int) *log.Logger
<not a function>
請注意,不可能同時打印參數的名稱和結果類型,因為它們無法存儲/訪問。
- 1 回答
- 0 關注
- 172 瀏覽
添加回答
舉報