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

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

如何使用反射獲得未導出的類型?

如何使用反射獲得未導出的類型?

Go
慕俠2389804 2022-11-08 10:38:13
想象一下,有人初始化了一個rpc 客戶端,client, _ := rpc.Dial('tcp', 'example.com:port')并且只為您提供了 rpc 客戶端實例。出于某種原因,您想example.com從客戶端實例中獲取地址。但是,由于客戶端類型是高度抽象的,您無法直接獲取net.Conn服務于方法的實例RemoteAddr()。在這種情況下,反射包可能會有所幫助。讓我們從以下嘗試開始:func getRemoteAddr(client *rpc.Client) net.Addr {  codec := reflect.Indirect(rpclient).FieldByName("codec")  connV := codec.FieldByName("rwc")  conn := connV.Interface().(net.Conn)  return conn.RemoteAddr()}然而,第二行立即跳出一個錯誤:panic: reflect: call of reflect.Value.FieldByName on interface Value這是合理的,因為它codec被聲明為類型ClientCodec,它只是一個具有四個方法簽名的接口。但是,從代碼中,我們知道詳細類型codec可能是未導出的 struct gobClientCodec。不幸的是,Go 編譯器不夠聰明,無法深入追蹤并找出實際類型。因此,反射包有沒有辦法告訴編譯器我對codec未導出的類型有信心gobClientCodec?如果這是不可能的,我可能不得不計算地址偏移量并使用不安全的指針,這是最后的選擇。PSType()反射方法中的默認方法不會像codec聲明的那樣工作,ClientCodec并通過在方法中傳遞gobClientCodec結構的地址來初始化,NewClient如下所示:func NewClient(conn io.ReadWriteCloser) *Client {    encBuf := bufio.NewWriter(conn)    client := &gobClientCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(encBuf), encBuf}    return NewClientWithCodec(client)}此外,reflect.TypeOf(rpc.gobClientCodec)不會像編譯器拒絕未導出的類型使用一樣工作。
查看完整描述

1 回答

?
元芳怎么了

TA貢獻1798條經驗 獲得超7個贊

用于.Elem()獲取接口中包含的值。

Elem 返回接口 v 包含的值或指針 v 指向的值。如果 v 的 Kind 不是 Interface 或 Ptr,它會發生恐慌。如果 v 為零,則返回零值。

對于您的特定用例,您還需要使用該unsafe包來訪問未導出的字段。在使用它之前,請務必閱讀 unsafe 的文檔。

func getRemoteAddr(client *rpc.Client) net.Addr {
  rv := reflect.ValueOf(client)
  rv = rv.Elem()               // deref *rpc.Client
  rv = rv.FieldByName("codec") // get "codec" field from rpc.Client
  rv = rv.Elem()               // get the value that ClientCodec contains
  rv = rv.Elem()               // deref *gobClientCodec
  rv = rv.FieldByName("rwc")   // get "rwc" field from gobClientCodec
  conn := *(*net.Conn)(unsafe.Pointer(rv.UnsafeAddr()))
  return conn.RemoteAddr()}

https://go.dev/play/p/cHHdwQJ7DE7


查看完整回答
反對 回復 2022-11-08
  • 1 回答
  • 0 關注
  • 86 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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