2012-03-18 16 views
8

Ok, devo ammettere che non uso molto Go, ma ho appena osservato qualcosa che mi sembra strano per un linguaggio che cerca la minimalità e tutto ciò che di buono come fa Go. Sarei sorpreso se non ci fosse una logica legittima dietro di esso, quindi è quello che sto cercando.Sintesi per la sintassi del metodo di Go

Quindi, quando si dispone di un metodo, si definisce in questo modo:

func (s *SomeStruct) Foo(x int) { } 

ma perché hanno un elenco di parametri in più solo per il "ricevitore", come mi pare si chiami? Non sarebbe un design più semplice e più elegante di fare proprio

func Foo(s *SomeStruct, x int) { } 

e poi hanno s.Foo(5) solo essere tradotto in una chiamata a una funzione Foo(s, 5)?

+0

La direzione che stai suggerendo è dove è andata la lingua Nim: http://nim-lang.org/docs/manual.html#procedures-method-call-syntax –

risposta

19

I metodi sono fondamentalmente speciali e diversi dalle normali funzioni.

  • I metodi devono vivere nello stesso pacchetto del tipo di destinatario.
  • I metodi sono utilizzati per soddisfare le interfacce.
  • I parametri del ricevitore sono gli unici parametri che possono essere sovraccaricati.
  • Quando i campi della struct anonimi hanno metodi, questi metodi sono "ereditati".

Con la proposta, la linea tra una funzione e un metodo diventa molto sfocata ed è difficile capire come risolvere i problemi precedenti.

Detto questo, penso che sarebbe davvero interessante progettare un linguaggio con multimetodi e interfacce. Tuttavia, quella lingua non sarebbe Go.

+0

Dai un'occhiata a Magpie, che usa multimethod, ed è scritto da un Dart Googler http://magpie.stuffwithstuff.com/multimethods.html –

+0

Grazie! Questo è esattamente il tipo di risposta che stavo cercando! – chisophugis

1

Probabilmente perché go non è Python.

Inoltre, perché a function declared this way is not a method.

Non è possibile dichiarare un metodo al di fuori del pacchetto di oggetti. Quindi immagino che la principale motivazione della differenza di sintassi tra metodi e funzioni sia quella di riuscire a differenziarli.

3

La sostituzione proposta non è semanticamente identica allo stato corrente, cioè non è solo una variazione sintattica. [Tenterà di] creare automaticamente metodi di qualsiasi tipo di pacchetto locale che è il primo parametro di una funzione. Considerando il modo in cui i set di metodi fondamentali sono legati al concetto di regole di soddisfazione dell'interfaccia automatica di Go, questo probabilmente porterà ad un grande casino.

In breve, penso che un tale cambiamento nel linguaggio Go non migliori nulla, danneggiando molte delle sue funzioni relative ai metodi e alle interfacce.

6

La tua domanda indica correttamente che qualsiasi metodo è una funzione. Tuttavia, la lingua Go deve essere in grado di distinguere esplicitamente tra metodi e funzioni. La ragione di ciò è che i metodi hanno caratteristiche che le funzioni non hanno. La scelta di se Foo è una funzione o un metodo che deve essere eseguito dal programmatore.

Il minimalismo di Go significa che la lingua definisce solo un piccolo insieme di parole chiave.Gli autori Go avrebbero potuto scegliere una nuova parola chiave, come ad esempio method, per distinguere i metodi da funzioni:

method Foo(receiver *T, arg1 int) {} // 'Foo' is a method, not a function 

Guardando in tutto il linguaggio di programmazione Go, possiamo vedere che la filosofia è quella di riutilizzare le parole chiave già esistenti piuttosto che avere una parola chiave separata per ogni occasione. Il for parola chiave è un buon esempio di questo approccio:

for {}      // Infinite loop 
for a>0 {a--}    // A while-do loop 
for i := range channel {} // Receive values from a channel 
for i:=0; i<N; i++ {}  // C-style for loop 

L'idea di base è che per il parser (and Go programmatori) per distinguere i vari tipi di for loop gli uni dagli altri, non v'è alcuna necessità di introdurre un nuova parola chiave se le opzioni possono essere distinte dalla sintassi di ciò che viene dopo la parola chiave for: ;:=rangeidentifier ..., il loro ordine sequenziale e la loro presenza/assenza.

La parola chiave func segue lo stesso schema. Può essere utilizzato in più contesti:

  • definizioni di funzioni: func f() {}
  • tipi di funzioni: type F func(int) int
  • metodo definizioni: func (t T) SomeMethod() {}
  • chiusure: { ...; go func(){c<-1}(); ...}

Dal punto di vista minimalista, un singolo La parola chiave func è sia più semplice che più elegante di avere più parole chiave.

L'elenco dei parametri in più solo per il ricevitore

func (t *T) Foo(x int) {} 

consente il parser di distinguere i metodi e funzioni:

func IDENTIFIER ...  This is going to be a function 
func (...    This is going to be a method 

Così, il parser (così come i programmatori Go) può fare la differenza in base al fatto che la parola chiave func sia seguita da un identificatore o da (.

Problemi correlati