問題:
在設計用於載入外掛程式的Go模組中,必須確保主包中存在具有預定名稱和簽名的特定函數。如果此函數不存在或與預期簽名不匹配,則需要一條描述性錯誤訊息。給定一個函數類型變量,如何取得底層簽名?
解:
只依賴reflect.Type.String()只提供類型的名稱,例如main.ModuleInitFunc。要檢索完整的簽名,我們必須使用reflect.Type提供的資訊手動建構它。
實作:
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() }
用法:
透過將函數變數傳遞給signature()函數,我們可以獲得相應的簽名作為字串。例如:
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(""))
輸出:
func (int) error func (int) error func () time.Time func (string) (*os.File, error) func (io.Writer, string, int) *log.Logger <not a function>
注意:
承認這是不可能的,這一點至關重要從簽名中提取參數名稱和結果類型,因為Go 不會儲存或提供對其的存取資訊。
以上是如何以字串形式檢索 Go 函數的簽章?的詳細內容。更多資訊請關注PHP中文網其他相關文章!