亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在go中獲取函數的簽名作為字符串

如何在go中獲取函數的簽名作為字符串

Go
波斯汪 2023-06-01 14:25:24
我正在實現一個加載 go 插件的 go 模塊。我假設主包中存在一個具有特定名稱和特定簽名的函數,并且希望在找不到它或與預期簽名不匹配時收到一條很好的錯誤消息。給定一個函數類型的變量,如何獲得該函數的底層簽名?以下僅打印類型的名稱(例如main.ModuleInitFunc)而不是完整的簽名。package mainimport "fmt"type ModuleInitFunc func(someInt int) errorfunc main() {    var myFunc ModuleInitFunc = nil    fmt.Printf("%T", lol)}
查看完整描述

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個參數的類型,同理返回第iType.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>

請注意,不可能同時打印參數的名稱和結果類型,因為它們無法存儲/訪問。


查看完整回答
反對 回復 2023-06-01
  • 1 回答
  • 0 關注
  • 172 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號