Maison >développement back-end >Golang >Comment rendre les fonctions Go génériques à l'aide d'interfaces : une solution de contrainte de type
Paramètres de méthode génériques dans Go : résoudre le problème des contraintes de type
Problème :
Considérez le code Go suivant :
<code class="go">package main import ( "fmt" "strconv" ) type Mammal struct { ID int Name string } type Human struct { ID int Name string HairColor string } func Count(ms []Mammal) *[]string { IDs := make([]string, len(ms)) for i, m := range ms { IDs[i] = strconv.Itoa(int(m.ID)) } return &IDs } func main() { ... // Code to create Mammal and Human slices numberOfMammalIDs := Count(mammals) numberOfHumanIDs := Count(humans) fmt.Println(numberOfMammalIDs) fmt.Println(numberOfHumanIDs) }</code>
Ce code ne parvient pas à se compiler avec l'erreur prog.go:39 : impossible d'utiliser les humains (type []Human) comme type []Mammal dans l'argument de Count. Le problème se pose parce que la fonction Count attend un tableau de structures Mammifères, alors que nous transmettons un tableau de structures Humaines. Comment pouvons-nous résoudre cette contrainte de type et rendre la fonction Count suffisamment générique pour accepter tout type possédant une propriété ID ?
Solution :
1. Utiliser des interfaces :
Remplacez les types concrets par des interfaces qui définissent la propriété ID. Par exemple :
<code class="go">type Mammal interface { GetID() int } type Human interface { Mammal GetHairColor() string }</code>
2. Interfaces intégrées :
Pour éviter de dupliquer la méthode d'identification dans les interfaces Mammifère et Humaine, utilisez des interfaces intégrées :
<code class="go">type MammalImpl struct { ID int Name string } func (m MammalImpl) GetID() int { return m.ID } type HumanImpl struct { MammalImpl HairColor string }</code>
3. Mettre à jour la fonction Count :
Modifiez la fonction Count pour utiliser l'interface Mammal au lieu du type concret Mammal :
<code class="go">func Count(ms []Mammal) *[]string { IDs := make([]string, len(ms)) for i, m := range ms { IDs[i] = strconv.Itoa(m.GetID()) } return &IDs }</code>
4. Créer des tranches compatibles avec l'interface :
Créez des tranches qui implémentent l'interface Mammal :
<code class="go">mammals := []Mammal{ MammalImpl{1, "Carnivorious"}, MammalImpl{2, "Ominivorious"}, } humans := []Mammal{ HumanImpl{MammalImpl: MammalImpl{ID: 1, Name: "Peter"}, HairColor: "Black"}, HumanImpl{MammalImpl: MammalImpl{ID: 2, Name: "Paul"}, HairColor: "Red"}, }</code>
5. Exemple d'utilisation :
Exemple d'utilisation qui se compile désormais avec succès :
<code class="go">package main import ( "fmt" "strconv" ) type Mammal interface { GetID() int } type Human interface { Mammal GetHairColor() string } type MammalImpl struct { ID int Name string } func (m MammalImpl) GetID() int { return m.ID } type HumanImpl struct { MammalImpl HairColor string } func (h HumanImpl) GetHairColor() string { return h.HairColor } func Count(ms []Mammal) *[]string { IDs := make([]string, len(ms)) for i, m := range ms { IDs[i] = strconv.Itoa(m.GetID()) } return &IDs } func main() { mammals := []Mammal{ MammalImpl{1, "Carnivorious"}, MammalImpl{2, "Ominivorous"}, } humans := []Mammal{ HumanImpl{MammalImpl: MammalImpl{ID: 1, Name: "Peter"}, HairColor: "Black"}, HumanImpl{MammalImpl: MammalImpl{ID: 2, Name: "Paul"}, HairColor: "Red"}, } numberOfMammalIDs := Count(mammals) numberOfHumanIDs := Count(humans) fmt.Println(numberOfMammalIDs) // [1 2] fmt.Println(numberOfHumanIDs) // [1 2] }</code>
En utilisant des interfaces et des interfaces intégrées, nous avons rendu la fonction Count suffisamment générique pour gérer tout type qui implémente le Interface mammifère, résolvant efficacement le problème de contrainte de type.
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!