2012-11-22 13 views
16

Ecco il programma per trovare il fattoriale di un numero in Go:codice Go non viene compilato senza un'istruzione return irraggiungibile

func factorial(x uint) uint { 
    if x == 0 { 
     return 1 
    } 

    return x * (factorial(x - 1)) 
} 

L'uscita per questa funzione quando viene chiamato in ingresso 5 è 120. Tuttavia, se aggiungo un'istruzione else, ottengo un errore.

func factorial(x uint) uint { 
    if x == 0 { 
     return 1 
    } else { 
     return x * (factorial(x - 1)) 
    } 
} 

Errore: function ends without a return statement

ho aggiunto un return alla fine:

func factorial(x uint) uint { 
    if x == 0 { 
     return 1 
    } else { 
     return x * (factorial(x - 1)) 
    } 
    fmt.Println("this never executes") 
    return 1 
} 

e torno l'uscita prevista di 120.

Perché secondo caso causerebbe un errore? Perché nel terzo caso, anche se la funzione non raggiunge mai l'ultimo return 1, calcola l'output corretto?

+1

È idiomatico in Vai a usare 'if cond {return}; return' (non su una riga ovviamente). Quando si hanno cicli infiniti dove nulla dopo il ciclo non viene eseguito, l'idioma comune è aggiungere "panic (" irraggiungibile ")'. –

+0

rende l'ultima istruzione un 'panico' ('mai raggiunto') ' – thwd

risposta

22

Questo è un problema ben noto del compilatore.

C'è anche un problema connesso: http://code.google.com/p/go/issues/detail?id=65

Nelle parole di uno dei del linguaggio Go autori:

I compilatori richiedono sia un ritorno o un panico di essere lessicalmente ultima in una funzione con un risultato. Questa regola è più semplice che richiedere l'analisi completa del controllo di flusso per determinare se una funzione raggiunge la fine senza ritorno (che è molto difficile in generale) e più semplice delle regole per enumerare casi facili come questo. Inoltre, essendo puramente lessicale, l'errore non può sorgere spontaneamente a causa di variazioni nei valori come le costanti utilizzate nelle strutture di controllo all'interno della funzione.

-Rob

Da un altro commento in golang-nuts, possiamo dedurre che non sta per essere "fisso" presto:

Non è un bug, è una decisione di progettazione deliberata.

-Rob

Nota che altri linguaggi come Java hanno regole che permettono questo else.


marzo 2013 EDIT - 'solo got changed in Go1.1:

Prima Go 1.1, una funzione che ha restituito un valore aveva bisogno di un esplicito "ritorno" o chiamare al panico, alla fine della funzione ; questo era un modo semplice per fare in modo che il programmatore fosse esplicito sul significato della funzione . Ma ci sono molti casi in cui un "ritorno" definitivo è chiaramente non necessario, come una funzione con un solo ciclo "for" infinito.

In Go 1.1, la regola relativa alle dichiarazioni finali "di ritorno" è più permissiva . Introduce il concetto di un'istruzione di chiusura, una dichiarazione che è garantita per essere l'ultima esecuzione di una funzione. Gli esempi includono "for" loop senza condizione e "if-else" dichiarazioni in cui ogni metà termina con un "ritorno". Se l'istruzione finale di una funzione di una funzione può essere sintatticamente considerata come un'istruzione di terminazione, non è necessaria alcuna istruzione finale "di ritorno".

Si noti che la regola è puramente sintattica: non presta attenzione ai valori nel codice e pertanto non richiede analisi complesse.

Aggiornamento: la modifica è compatibile con le versioni precedenti, ma il codice esistente con dichiarazioni di reso superflui e le chiamate al panico possono essere semplificate manualmente . Tale codice può essere identificato dal veterinario.

E la questione che ho citato è chiuso con lo stato "fisso".

Problemi correlati