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

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

有沒有辦法使用反射來辨別圍棋中的類型關系?

有沒有辦法使用反射來辨別圍棋中的類型關系?

Go
三國紛爭 2022-08-24 20:16:45
上下文為 Go 語言庫編寫 URL 查詢參數解析器問題只有結構在Go中具有我所知道的繼承形式??梢允褂梅瓷浒鼇肀鎰e實體的類型,即它是類型系統中的基本存儲類,并且可以探測所述元素的類型。因此,我可以辨別出該實體是 Kind 字符串,并且類型 Title 作為任意示例,假設存在類似這樣的東西:type Title string更好的是,對于結構,我可以使用匿名成員來獲得有限類型的繼承:type Foo struct { name string }func (f Foo) Hello() string { return f.name; }type Bar struct { Foo }func main() {  b := Bar{ Foo{"Simon"} }  fmt.Println(b.Hello())}實際示例關鍵是,Go允許我將Foo擴展為Bar,但至少對于Foo的部分繼承/重用Foo函數。但是,對于非結構類型 - 我不知道如何為類似于json或xml的編碼/解碼庫解決這個問題 - 我希望能夠將查詢參數解碼為結構的成員,并且至關重要的是,能夠支持用戶定義的類型,而不需要它們中的每一個都為我的目的定義一個專門的解碼器或編碼器, 只要它們是支持我可以利用的接口的類型的衍生品。具體來說,我想支持存儲為Google uuid的用戶定義類型。UUID,或一個時間。時間(或時間。持續時間也將是有用的)。下面是一個簡單的示例:type TransactionID uuid.UUID如前所述,這將繼承 uuid 的零行為。UUID,我不確定是否或如何使用反射來故意在我的編碼器/解碼器庫中發生這種情況?Go本身不會在它們之間提供任何形式的繼承或關系。我的事務 ID 不是 uuid。UUID,但它們共享相同的種類 - 一個[16]字節數組,據我目前所知,這就是它們共享的全部內容。這是我的難題如何允許我希望支持的用戶定義類型,而無需我的用戶現在為其類型定義我已經為“基本”類型定義的相同編碼器或解碼器函數?更多背景信息我的解碼器庫提供此接口:// Parser is an interface for types that RequestParser can parse from a URL parametertype Parser interface {    ParseParameter(value string) error}我為uuid定義了一個專門的擴展。UUID 和時間。Time 和其他一些有用的非結構類型,用于從查詢參數字符串中解碼它們。如果我正在解碼的實體類型實際上是一個uuid。UUID 或一個時間。時間而不是基于這些的用戶定義類型,然后事情就會正常工作。同樣,用戶別名之所以有效,是因為它們不是真正的新類型。別名對于我的目的來說太有限了 - 它們沒有提供與別名類型的任何有意義的區別,這嚴重限制了它們的實際效用。我不會回應需要使用它們的建議。謝謝。更新理想情況下,用戶應該能夠為他們的目的定義TransalID,我想知道它是一種“一種”UUID,因此 - 默認情況下 - 使用UUID解析器。用戶定義:func (id *TransactionID) ParseParameter(value string) (err error) {   id_, err := uuid.Parse(value)   if err != nil {      return   }   *id = TransactionID(id_)   return}這將迫使我的解碼器選擇他們明確定義的接口 - 并完全按照他們希望的類型解碼輸入。我希望 - 是有一種方法可以知道他們的類型是____的衍生類型是什么?,如果我有一個____的解析器是什么 - 那么 - 在沒有用戶定義的ParseParameter的情況下 - 使用我默認提供的智能(知道[16]字節與UUID不是一回事, 并了解更復雜的解碼UUID的方法)。補遺我將擴展這個問題,并在我得到深思熟慮和有用的答復時提供更多細節。我不確定在這一點上我還能提供什么?感謝您花時間深思熟慮地回復,如果您選擇這樣做。
查看完整描述

1 回答

?
慕容708150

TA貢獻1831條經驗 獲得超4個贊

無法使用反射 API 來辨別一個類型是從另一個類型創建的。

規范說

類型定義創建一個新的、不同的類型,其基礎類型和操作與給定類型相同,并將標識符綁定到該類型。

新類型稱為已定義類型。它不同于任何其他類型,包括創建它的類型。

該規范未定義已定義類型與創建該類型時所基于的類型之間的任何其他關系。沒有“創建自”關系供反射 API 公開。

在示例中

type A B

反射 API 無法告訴您類型 A 是從類型 B 創建的,因為除了共享的基礎類型之外,類型 A 和類型 B 之間沒有關系。

允許從 A 到 B 和 B 到 A 的類型轉換,因為 A 和 B 具有相同的基礎類型。

您可以使用反射 API 來確定兩個類型是否具有相同的基礎類型,但這對解決問題沒有幫助??赡苁茿是從B創建的,B是從A創建的,或者兩者都不是從另一個創建的。在此示例中,類型 A 和 B 具有相同的基礎類型:

 type A int
 type B int

問題指出,解析器具有 的內置解碼器。目標是將該解析器用于 。以下是解決此問題的一些方法:uuid.UIDtype TransactionID uuid.UUID

嵌入將類型聲明為 。檢查具有單個已知嵌入字段的結構并相應地進行處理。type TransactionID struct { uuid.UID }

注冊表添加函數函數以注冊可轉換類型之間的映射。

 var decodeAs  = map[reflect.Type]reflect.Type{} 
 func RegisterDecodeAs(target, decode reflect.Type) {
      if !decode.ConvertibleTo(target) {
              panic("type must be convertible")
     }
     decodeAs[target] = decode
 }

解碼時,請檢查 中的解碼類型。如果存在,則解碼為解碼類型,轉換為目標類型并分配。decodeAs

在程序啟動時調用注冊函數:

 func init() {
     RegisterDecodeAs(reflect.TypeOf(TransactionID(nil)), reflect.TypeOf(uuid.UUID(nil))
 }


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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