Maison >développement back-end >Golang >Comment puis-je faire la distinction entre les types intégrés et personnalisés à l'aide du package « reflect » de Go ?

Comment puis-je faire la distinction entre les types intégrés et personnalisés à l'aide du package « reflect » de Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-28 20:24:10280parcourir

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

Identifier les types non intégrés à l'aide de Reflect

Le défi

Vous devez distinguer des types comme type A []byte from []byte en utilisant le package Reflect. Reflect.TypeOf(A{}).Kind renvoie Slice pour les deux types, ce qui rend difficile leur distinction.

Contexte sur les types

  • Les types nommés sont défini à l'aide d'une déclaration de type (par exemple, tapez MyInt int).
  • Les types sans nom sont des littéraux de type (par exemple, []int, struct{i int}).
  • Les types prédéfinis (par exemple, string, int) sont disponibles pour une utilisation immédiate.

Approche

Utilisation des méthodes de type réflexion :

  • Name() : renvoie le nom d'un type nommé ; vide pour les types sans nom.
  • PkgPath() : renvoie le chemin du package d'un type nommé ; vide pour les types prédéclarés ou sans nom.
  • Elem() : renvoie le type d'élément des tableaux, canaux, cartes, pointeurs et tranches.

Cas spéciaux

  • Types de structures anonymes : parcourir les champs et vérifier la personnalisation types.
  • Types de cartes : vérifiez les types de clé et de valeur.

Implémentation

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
}

Tests

Appliquer ceci à divers types :

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

Cela démontre la capacité de différencier les types intégrés et personnalisés en utilisant efficacement le package Reflect.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn