Maison >développement back-end >Golang >Obtenez le nom de type d'une structure générique sans paramètres de type
Dans cet article, l'éditeur PHP Strawberry vous présentera comment obtenir le nom de type d'une structure générique sans paramètres de type. Les génériques sont une technique de programmation puissante qui vous permet d'écrire du code générique sans spécifier de types spécifiques. Cependant, nous pouvons parfois avoir besoin d'obtenir le nom de type d'une structure générique sans contenir de paramètres de type spécifiques. Cet article répondra à cette question en détail pour vous et vous aidera à mieux comprendre et appliquer la programmation générique.
Supposons que j'ai un type spécifique nommé foo
的通用结构,我从中创建了两个对象。我可以使用 reflect.typeof()
identifiant chacun comme suit :
package main import ( "fmt" "reflect" ) type foo[t any] struct { data t } func main() { a := foo[string]{"cheese"} b := foo[int]{42} fmt.println(reflect.typeof(a)) fmt.println(reflect.typeof(b)) } // main.foo[string] // main.foo[int]
Je souhaite déterminer le type commun (c'est-à-dire foo
),而不是具体类型(即 foo[string]
和 foo[int]
) de ces objets. Est-ce possible ou dois-je extraire manuellement le type générique de ces chaînes (par exemple en utilisant des expressions régulières) ?
Une expression régulière pourrait ressembler à ceci :
func GetGenericType(x any) string { // Get type as a string s := reflect.TypeOf(x).String() // Regex to run r := regexp.MustCompile(`\.(.*)\[`) // Return capture return r.FindStringSubmatch(s)[1] } fmt.Println(GetGenericType(a)) fmt.Println(GetGenericType(b)) // foo // foo
J'ai aussi vu cette question, mais cela ne répond pas à la question car elle donne le type spécifique (c'est-à-dire main.foo[string]
)而不是通用类型(即, foo
).
Reflection ne peut pas voir le nom d'un type générique "de base" car le type de base n'existe pas au moment de l'exécution.
Le paragraphe pertinent dans la spécificationgo est instantiation :
L'instanciation d'un type produit un nouveau type nommé non générique ; l'instanciation d'une fonction produit une nouvelle fonction non générique.
Alors quand tu écris :
b := foo[int]{42} name := reflect.typeof(b).name()
Le nom du type est exactement foo[int]
.
Il convient de noter qu'un identifiant foo
sans liste d'arguments de type est pertinent au moment de la compilation, car il vous empêche de le redéclarer dans le même package. Définition du type :
La définition du type crée un nouveau type différent avec le même type Le type et l'opération sous-jacents sont donnés comme type et lié Identifiant, tapez le nom, donnez-le .
typedef = identifier [ typeparameters ] type .
Cependant, comme mentionné ci-dessus, l'instanciation produit un nouveau type nommé différent de foo
; au moment de l'exécution, vous ne traitez l'instanciation que lorsque vous pouvez utiliser la réflexion.
En résumé, je pense que votre solution regex est acceptable jusqu'à ce que certaines fonctions d'assistance soient ajoutées à stdlib (le cas échéant). Republier ici pour plus de clarté :
func getgenerictype(x any) string { // get type as a string s := reflect.typeof(x).string() // regex to run r := regexp.mustcompile(`\.(.*)\[`) // return capture return r.findstringsubmatch(s)[1] }
Rappelez-vous la différence entre type.string()
和 type.name()
: n'importe quel type peut avoir une représentation sous forme de chaîne, mais seuls les types nommés ont des noms. (Évidemment, non ?). Par exemple, si vous écrivez :
b := &foo[int]{42}
Ensuite b
的类型为*foo[int]
,为匿名复合类型,name()
renvoie une chaîne vide.
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!