2017-08-11 1 views
0

Je voudrais créer une structure de base qui doit avoir une méthode, je veux utiliser ces méthodes dans les substrats. Par exemple:Golang base struct pour définir des méthodes dans les substructures

type Base struct { 
    Type string `json:"$type"` 
} 

func (b Base) GetJSON() ([]byte, error) { 
    return json.Marshal(b) 
} 

func (b Base) SetType(typeStr string) interface{} { 
    b.Type = typeStr 
    return b 
} 

Dans la nouvelle struct je veux l'utiliser comme ceci:

type Auth struct { 
    Base 
    Username 
    Password 
} 

et appeler ces méthodes dans la principale:

func main() { 
    a := Auth{ 
    Username: "Test", 
    Password: "test", 
    } 
    a = a.SetType("testtype").(Auth) 
    j, _ := a.GetJSON() 
} 

Dans le cas setType je suis arrivé une panique provoquée par l'interface {} n'est pas de type Auth, elle est de type Base. Dans le cas de GetJSON j'ai eu un json sur le type, mais seulement le type.

Y at-il une solution au problème que je veux résoudre?

+1

'retour b.Type = typeStr' n'est pas une instruction valide Go. Base ne va pas avoir les champs "Nom d'utilisateur" et "Mot de passe" si c'est ce que vous essayez de faire. Il n'y a pas d'héritage dans Go. – JimB

+0

Je recommanderais de repenser votre conception entièrement à partir d'une perspective Go. Go n'est pas un langage orienté objet. Il n'a pas d'héritage, et pas de polymorphisme au-delà des interfaces. – Adrian

+0

Oui, je le sais, mais comment les gens résolvent le problème donné, je les ai tous structurés avec les mêmes méthodes, devrais-je les écrire à tous? – PumpkinSeed

Répondre

1

Comme mentionné dans les commentaires, intégrez est pas l'héritage, mais la composition, de sorte que vous aurez probablement soit:

  • Repensez votre conception à utiliser les outils Go disponibles a
  • Resort à une vaste le piratage pour obtenir les résultats que vous voulez

Dans le cas particulier que vous montrez (essayer d'obtenir GetJSON() d'inclure également les champs de la structure extérieure, voici un moyen possible d'obtenir que le travail qui ne nécessite pas beaucoup changements (juste stocker un pointeur vers la structure externe dans la base lors de la création du struct):

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Base struct { 
    Type string  `json:"$type"` 
    selfP interface{} // this will store a pointer to the actual sub struct 
} 

func (b *Base) SetSelfP(p interface{}) { 
    b.selfP = p 
} 

func (b *Base) GetJSON() ([]byte, error) { 
    return json.Marshal(b.selfP) 
} 

func (b *Base) SetType(typeStr string) { 
    b.Type = typeStr 
} 

type Auth struct { 
    Base 
    Username string 
    Password string 
} 

func main() { 
    a := &Auth{ 
     Username: "Test", 
     Password: "test", 
    } 
    a.SetSelfP(a) // this line does the trick 
    a.SetType("testtype") 
    j, _ := a.GetJSON() 
    fmt.Println(string(j)) 
} 

lien Playground: https://play.golang.org/p/npuy6XMk_t

+0

Merci, c'est exactement ce que je cherche. – PumpkinSeed