首頁 >後端開發 >Golang >我們如何使用 Go 反射區分自訂類型和內建類型?

我們如何使用 Go 反射區分自訂類型和內建類型?

Mary-Kate Olsen
Mary-Kate Olsen原創
2025-01-05 03:09:39819瀏覽

How Can We Distinguish Custom Types from Built-in Types Using Go Reflection?

使用反射識別非內建類型

識別自訂類型

為了區分自訂類型和預定義類型,我們可以使用兩種反射方法:

  • Type.PkgPath():傳回命名類型的封包路徑。預定義類型有一個空的包路徑。
  • Type.Name():傳回命名類型的名稱。未命名類型傳回一個空字串。

自訂類型將具有非空白套件路徑和非空白名稱。相反,預定義類型將具有空包路徑。

處理特殊情況

匿名結構類型:

匿名結構類型未命名,但可能有自訂類型的欄位。我們可以透過迭代結構體的欄位並檢查其中是否有自訂類型來檢查自訂類型。

映射類型:

映射類型可以具有自訂鍵或值類型。我們可以使用 Type.Elem() 查詢值類型,使用 Type.Key() 查詢鍵類型。

實作範例

func isCustom(t reflect.Type) bool {
    if t.PkgPath() != "" {
        return true
    }

    if k := t.Kind(); k == reflect.Array || k == reflect.Chan || k == reflect.Map ||
        k == reflect.Ptr || k == reflect.Slice {    
        return isCustom(t.Elem()) || (k == reflect.Map && isCustom(t.Key()))
    } else if k == reflect.Struct {
        for i := t.NumField() - 1; i >= 0; i-- {
            if isCustom(t.Field(i).Type) {
                return true
            }
        }
    }

    return false
}

檢定

fmt.Println(isCustom(reflect.TypeOf("")))                // false
fmt.Println(isCustom(reflect.TypeOf(int(2))))            // false
fmt.Println(isCustom(reflect.TypeOf([]int{})))           // false
fmt.Println(isCustom(reflect.TypeOf(struct{ i int }{}))) // false
fmt.Println(isCustom(reflect.TypeOf(&i)))                // false
fmt.Println(isCustom(reflect.TypeOf(map[string]int{})))  // false
fmt.Println(isCustom(reflect.TypeOf(A{})))               // true
fmt.Println(isCustom(reflect.TypeOf(&A{})))              // true
fmt.Println(isCustom(reflect.TypeOf([]A{})))             // true
fmt.Println(isCustom(reflect.TypeOf([][]A{})))           // true
fmt.Println(isCustom(reflect.TypeOf(struct{ a A }{})))   // true
fmt.Println(isCustom(reflect.TypeOf(map[K]int{})))       // true
fmt.Println(isCustom(reflect.TypeOf(map[string]K{})))    // true

以上是我們如何使用 Go 反射區分自訂類型和內建類型?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn