In Vai quando scrivere una funzione con o senza ricevitore?

-1

Stiamo cercando di scrivere Go nel modo più idiomatico possibile, ma a volte facciamo fatica a trovare quale sia il modo migliore.

Ad esempio, nel nostro servizio stiamo creando / convertendo una struttura da un'altra:

type Foo struct {
    ID int
}

type Bar struct {
    ID int
}

È meglio scrivere qualcosa come:

func convertAtoB(a A) *B {
    return &B{a.ID}
}

o qualcosa di simile?

func (a* A) convertToB() *B {
    return &B{a.ID}
}

Ovviamente nella pratica non c'è differenza, vorrei solo capire quando scegliere un modo rispetto all'altro.

Modifica

Ho trovato un interessante articolo su questo:
link

    
posta Enrichman 10.08.2017 - 17:52
fonte

2 risposte

4

Ci sono due ragioni per usare le funzioni con i ricevitori:

  1. Invocherai il metodo tramite un tipo di interfaccia.
  2. Ti piace molto la sintassi della chiamata al metodo.

In tutti gli altri casi (di cui sono a conoscenza), sono preferibili le normali funzioni senza argomenti del ricevitore.

    
risposta data 10.08.2017 - 18:40
fonte
1

Recentemente sono incappato in una cosa correlata al ricevitore che in qualche modo molto rapidamente qualcuno sul Github mi ha trovato la risposta che stavo cercando. Giusto per spiegare, quello che volevo era essere in grado di incorporare una funzione di prima classe che aveva un ricevitore - in questo caso che era esattamente il tipo di struttura in cui volevo inserirlo. Ho trovato una soluzione alternativa utilizzando la sintassi di func di tipo Name e quindi la creazione di una funzione privata che è stata racchiusa in un ricevitore con tipo vincolato da un'interfaccia, ma questo mi consente di farlo in modo diverso: la soluzione era ingombrante e generosa.

Ecco il problema con Github:

link

Non sono stato in grado di trovare ulteriore documentazione su questo, ma essenzialmente i punti principali sono che puoi creare un campo interface {} in un tipo struct, e quindi assegnare una funzione legata a una collezione di metodi di interfaccia, come questa :

type Name Struct {
  ...
  funcSlot interface{}
  ...
}

func (n *Name) FuncName() error {
  return nil
}

func NewName() (n *Name) {
  ...
  n.funcSlot = (*Name).FuncName
  ...
}

type NAME interface {
  ...
  FuncName() error
  ...
}

Questo passaggio passa al veterinario, almeno, non ho ancora confermato che questo abbia l'effetto di passare il puntatore alla struct in modo che la funzione possa operare su ciò che effettivamente è una classe.

    
risposta data 23.04.2018 - 09:19
fonte

Leggi altre domande sui tag