第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

如何使用反射獲得未導(dǎo)出的類型?

如何使用反射獲得未導(dǎo)出的類型?

Go
慕俠2389804 2022-11-08 10:38:13
想象一下,有人初始化了一個rpc 客戶端,client, _ := rpc.Dial('tcp', 'example.com:port')并且只為您提供了 rpc 客戶端實(shí)例。出于某種原因,您想example.com從客戶端實(shí)例中獲取地址。但是,由于客戶端類型是高度抽象的,您無法直接獲取net.Conn服務(wù)于方法的實(shí)例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這是合理的,因?yàn)樗點(diǎn)odec被聲明為類型ClientCodec,它只是一個具有四個方法簽名的接口。但是,從代碼中,我們知道詳細(xì)類型codec可能是未導(dǎo)出的 struct gobClientCodec。不幸的是,Go 編譯器不夠聰明,無法深入追蹤并找出實(shí)際類型。因此,反射包有沒有辦法告訴編譯器我對codec未導(dǎo)出的類型有信心gobClientCodec?如果這是不可能的,我可能不得不計(jì)算地址偏移量并使用不安全的指針,這是最后的選擇。PSType()反射方法中的默認(rèn)方法不會像codec聲明的那樣工作,ClientCodec并通過在方法中傳遞gobClientCodec結(jié)構(gòu)的地址來初始化,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)不會像編譯器拒絕未導(dǎo)出的類型使用一樣工作。
查看完整描述

1 回答

?
元芳怎么了

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個贊

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

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

對于您的特定用例,您還需要使用該unsafe包來訪問未導(dǎo)出的字段。在使用它之前,請務(wù)必閱讀 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


查看完整回答
反對 回復(fù) 2022-11-08
  • 1 回答
  • 0 關(guān)注
  • 90 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號