Maison > développement back-end > Golang > Comment créer un objet non nul d'une valeur typée dans les génériques Go 1.18 ?

Comment créer un objet non nul d'une valeur typée dans les génériques Go 1.18 ?

Patricia Arquette
Libérer: 2024-12-10 08:11:12
original
151 Les gens l'ont consulté

How to Create a Non-Nil Object of a Typed Value in Go 1.18 Generics?

Créer un nouvel objet de valeur typée via Go (go 1.18) Generics

Lorsque vous travaillez avec des génériques dans Go 1.18, vous pouvez rencontrer une situation où vous devez créer un nouvelle instance d'un type personnalisé dans une fonction générique. Le problème suivant illustre ce défi :

Problème

Dans l'exemple de code fourni, la fonction Create dans la structure FruitFactory est destinée à créer une nouvelle instance de type T, mais elle renvoie actuellement zéro. Cela entraîne une erreur de segmentation lors de la tentative d'accès aux attributs de l'objet.

type FruitFactory[T any] struct{}

func (f FruitFactory[T]) Create() *T {
    // How to create non-nil fruit here?
    return nil
}

type Apple struct {
    color string
}

func example() {
    appleFactory := FruitFactory[Apple]{}
    apple := appleFactory.Create()
    // Panics because nil pointer access
    apple.color = "red"
}
Copier après la connexion

Solution

Pour résoudre le problème, nous devons modifier la fonction Create pour renvoyer une instance valide de type T. Il existe deux approches pour y parvenir :

Approche 1 (sans pointeur Types)

Si le type personnalisé n'est pas un type pointeur (comme la structure Apple), vous pouvez déclarer une variable typée et renvoyer son adresse :

func (f FruitFactory[T]) Create() *T {
    var a T
    return &a
}
Copier après la connexion

Approche 2 (Types de pointeur)

Si le type personnalisé est un type de pointeur (comme *Apple), la solution est plus complexe. Vous pouvez exploiter la puissance de l'inférence de type pour contraindre le type de l'usine aux types de pointeurs :

// Constraining a type to its pointer type
type Ptr[T any] interface {
    *T
}

// The first type param will match pointer types and infer U
type FruitFactory[T Ptr[U], U any] struct{}

func (f FruitFactory[T,U]) Create() T {
    // Declare var of non-pointer type. This is not nil!
    var a U
    // Address it and convert to pointer type (still not nil)
    return T(&a)
}

type Apple struct {
    color string
}

func example() {
    // Instantiating with ptr type
    appleFactory := FruitFactory[*Apple, Apple]{}
    apple := appleFactory.Create()

    // All good
    apple.color = "red"

    fmt.Println(apple) // &{red}
}
Copier après la connexion

Remarque : Pour l'approche 2, l'inférence de type a été désactivée dans Go 1.18, donc vous devez spécifier manuellement tous les paramètres de type, tels que : FruitFactory[*Apple, Apple]{}.

Avec ces modifications, la fonction Create retournera un valide instance de type T (ou *T), permettant d'accéder à ses attributs sans provoquer d'erreurs de segmentation.

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!

source:php.cn
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal