Maison  >  Article  >  développement back-end  >  Obtenez le nom de type d'une structure générique sans paramètres de type

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

王林
王林avant
2024-02-13 12:27:071188parcourir

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]

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

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

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer