Maison > développement back-end > Golang > le corps du texte

Obtenez le nom de type d'une structure générique sans paramètres de type

王林
Libérer: 2024-02-13 12:27:07
avant
1150 Les gens l'ont consulté

Obtenez le nom de type dune 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.

Contenu de la question

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]
Copier après la connexion

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) ?

Modifier

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

Copier après la connexion

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).

Solution

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écification

go 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()
Copier après la connexion

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 .
Copier après la connexion

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]
}
Copier après la connexion

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}
Copier après la connexion

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!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!