L'obiettivo principale di Go è di essere semplice da imparare e semplice da usare anche per programmatori sub-mediocri, quindi se vuoi scrivere in modo idiatico Vai l'anti-pattern che dovresti evitare di più è l'anti-pattern "Clever Code" .
Per una buona ragione per non consentire le funzioni annidate anche se si consentono le funzioni anonime - una delle differenze tra Python e Go è che Python non ha bisogno di una funzione main
. Puoi semplicemente scrivere:
def foo():
print('hi')
foo()
e l'interprete Python inizierebbe a leggere dall'alto verso il basso. Quando raggiunge def foo():
creerà una funzione e quando raggiungerà foo()
eseguirà quella funzione. L'interprete è sempre nella stessa modalità (che è, almeno, l'astrazione) - la modalità di lettura e valutazione. Funziona allo stesso modo sia all'interno che all'esterno di una funzione, quindi è facile per esso supportare la copia di tutto quel codice all'interno di una funzione: aggiungerà semplicemente un'altra cornice al suo callstack e a parte questo farà esattamente la stessa cosa.
Go è una storia diversa. Quando scrivi
func foo() {
fmt.Println("hi")
}
func main() {
foo()
}
Il compilatore legge il livello più alto in modalità dichiarativo e crea le funzioni, ma il corpo delle funzioni che legge nella modalità imperativo . Nella modalità dichiarativa può creare funzioni e in modalità imperativo può eseguire istruzioni. Per abilitare le funzioni annidate sarà necessario aggiungere funzionalità di dichiarazione delle funzioni alla modalità imperativo .
Quindi, si potrebbe chiedere, non aggiungere questa funzionalità alla modalità imperativo ? Il motivo principale è la gestione delle chiusure:
func main() {
txt := "hi"
func foo() {
fmt.Println(txt)
}
foo()
}
Scrivere qualcosa del genere significa che foo
non è una funzione regolare - ha bisogno di accedere a txt
, che risiede nello stack frame di main
, quindi ha bisogno di un puntatore di contesto quello indicherà quel telaio. Se main
viene richiamato, verrà creato un altro foo
con un puntatore di contesto diverso.
Questo rende le funzioni annidate essenzialmente diverse dalle funzioni regolari, il che è un motivo per non avere funzioni annidate. Python non ha questo problema, perché tutte le sue funzioni sono le chiusure - sono tutte "annidate".