Maison  >  Article  >  développement back-end  >  Passer aux génériques : littéral composé invalide

Passer aux génériques : littéral composé invalide

王林
王林avant
2024-02-08 22:00:111205parcourir

Go 泛型:无效的复合文字

l'éditeur php Xigua vous apporte les dernières informations - "Go Generics : littéral composé invalide". Dans la communauté linguistique Go, les génériques ont toujours été un sujet de grande préoccupation. Avec la sortie de Go 1.18, les génériques seront officiellement inclus dans la bibliothèque standard du langage Go. Cependant, cette décision n’a pas été acceptée par tout le monde. Cet article discutera de la mise en œuvre des génériques dans le langage Go et des controverses et discussions associées pour aider les lecteurs à mieux comprendre cette technologie et fournir une référence pour son application dans le développement réel.

Contenu de la question

Le code suivant provoque l'erreur "Type littéral composé non valide t".

package main

import "fmt"

func main() {
    fmt.Println(createThing[foo]())
}

type thing interface {
    foo | bar
}

type foo struct {
    id int
    a  string
}

type bar struct {
    id int
    b  int
}

func createThing[T thing, P *T]() P {
    return &T{}
}

Si je fais simplement en sorte que l'interface thing中包含thing,或者删除a stringb int,那么foobar soit exactement la même, le code s'exécutera sans erreur. Cependant, cela va-t-il à l’encontre de l’objectif des génériques ? Pourquoi ne puis-je pas instancier un type générique comme celui-ci, surtout lorsque je n'ai même accès à aucun champ ?

Peut-être lié à https://github.com/golang/go/issues/48522

Solution de contournement

La plupart des types génériques ne sont pas des types valides pour les littéraux composés. Mais ce n'est pas un problème car il existe d'autres moyens de créer des valeurs de types génériques.

Créez un pointeur vers la nouvelle valeur zéro :

func creatething[t thing]() *t {
    return new(t)
}

Ou créez une valeur zéro sans pointeur :

func createThing[T thing]() T {
    var value T
    return value
}

Quant à pourquoi une erreur se produit de cette manière, voici l'explication de la spécification, modifiée pour résoudre votre problème spécifique.

Pour texte composé :

Le type de base t de literaltype doit être un type structure, tableau, slice ou map

Quel est le type de noyau ?

L'interface t a des types de base si [...] un seul type u existe, qui est le type sous-jacent pour tous les types de l'ensemble de types de t

Aucune autre interface n'a de types de base.

Quel est le type sous-jacent ?

Chaque type t a un type sous-jacent : si t est l'un des types booléens, numériques ou chaînes prédéclarés, ou un type littéral, le type sous-jacent correspondant est t lui-même. Sinon, le type sous-jacent de t est le type sous-jacent du type référencé par t dans sa déclaration.

"Les littéraux de type" peuvent faire référence à des types structurels littéraux, par exemple struct{int id}。因此,当 foobar 都具有 struct{int id}底层类型时,则 thing 具有 struct{int id}核心类型,因此复合文字是可能的。当 foobar 没有相同的底层类型时,则 thing Il n'y a pas de types de base et les littéraux composés ne sont pas possibles, d'où votre erreur.

La définition formelle peut paraître complexe, mais le résultat et le point pratique sont simples : le code générique ne peut exprimer que le comportement commun des types possibles. Les valeurs littérales ne constituent pas un comportement courant, sauf dans le cas particulier où tous les types sous-jacents sont identiques.

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