Heim >Backend-Entwicklung >Golang >Wie kann ich mit dem „reflect'-Paket von Go zwischen integrierten und benutzerdefinierten Typen unterscheiden?

Wie kann ich mit dem „reflect'-Paket von Go zwischen integrierten und benutzerdefinierten Typen unterscheiden?

Barbara Streisand
Barbara StreisandOriginal
2024-12-28 20:24:10304Durchsuche

How Can I Distinguish Between Built-in and Custom Types Using Go's `reflect` Package?

Identifizieren nicht integrierter Typen mithilfe von Reflect

Die Herausforderung

Sie müssen unterscheiden Typen wie Typ A []Byte aus []Byte mithilfe des Reflect-Pakets. reflektieren.TypeOf(A{}).Kind gibt Slice für beide Typen zurück, was es schwierig macht, sie zu unterscheiden.

Hintergrundinformationen zu Typen

  • Benannte Typen sind definiert mit einer Typdeklaration (z. B. Typ MyInt int).
  • Unbenannte Typen sind Typliterale (z. B. []int, struct{i int}).
  • Vordeklarierte Typen (z. B. string, int) stehen zur sofortigen Verwendung zur Verfügung.

Ansatz

Verwendung der Methoden des Reflect-Typs:

  • Name(): Gibt den Namen von zurück ein benannter Typ; leer für unbenannte Typen.
  • PkgPath(): Gibt den Paketpfad eines benannten Typs zurück; leer für vordeklarierte oder unbenannte Typen.
  • Elem(): Gibt den Elementtyp von Arrays, Kanälen, Karten, Zeigern und Slices zurück.

Sonderfälle

  • Anonyme Strukturtypen: Durchlaufen Sie Felder und prüfen Sie, ob sie benutzerdefiniert sind Typen.
  • Kartentypen: Überprüfen Sie sowohl Schlüssel- als auch Werttypen.

Implementierung

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
}

Testen

Anwenden auf verschiedene Typen:

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

Dies demonstriert die Fähigkeit, mithilfe des Reflect-Pakets effektiv zwischen integrierten und benutzerdefinierten Typen zu unterscheiden.

Das obige ist der detaillierte Inhalt vonWie kann ich mit dem „reflect'-Paket von Go zwischen integrierten und benutzerdefinierten Typen unterscheiden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn