2014-10-31 9 views
5

Sto imparando Scala e ho notato qualcosa sull'uso dell'istruzione return.Qual è la differenza tra l'utilizzo dell'istruzione return e l'impostazione predefinita per restituire l'ultimo valore?

Quindi, ovviamente in Scala, se non si dispone di un'istruzione di ritorno, l'ultimo valore viene restituito per impostazione predefinita. Che è grandioso. Ma se si utilizza l'istruzione return senza specificare il tipo di ritorno, Scala dice "error: method testMethod has return statement; needs result type"

Quindi questo funziona

def testMethod(arg: Int) = { 
    arg*2 
    } 

ma questo dà l'errore

def testMethod(arg: Int) = { 
    return arg*2 
    } 

Questo mi fa grattare il mento e vado

Mmmmmmmm ... Ci deve essere una ragione per questo.

Perché è necessaria la dichiarazione del tipo esplicito quando si utilizza un'istruzione return ma non quando si consente a Scala di restituire l'ultimo valore? Ho pensato che fossero esattamente la stessa cosa, e che le dichiarazioni di ritorno sono solo per se si desidera restituire un valore all'interno di una funzione nidificata/condizionale, ecc. (In altre parole, che un'istruzione di "ritorno" viene automaticamente inserita nell'ultimo valore dal compilatore .. se non presente altrove nel metodo)

Ma chiaramente mi sbagliavo. Sicuramente ci deve essere qualche altra differenza nell'implementazione?

Mi manca qualcosa?

+0

ho immaginato che non viene compilato perché si sta in realtà utilizza la parola chiave 'return' e Avevo ragione. Pubblicherò la mia risposta tra un secondo. Fondamentalmente, se usi return, cercherai di dichiarare il suo tipo restituito invece di inferire il tipo restituito da solo. – Luminous

risposta

4

Se si dispone di più punti di uscita dal metodo, potrebbe essere impossibile per il compilatore inferire il tipo restituito. L'unico modo per ottenere più punti di uscita dal metodo è utilizzare più return s. (O uno return più il ritorno implicito.)

Poiché le regole, quando funziona e quando non lo sono, sono piuttosto complesse, può sembrare all'utente che a volte funziona a caso e talvolta no. Semplicemente vietando del tutto l'inferenza di tipo in presenza di un esplicito return è una regola molto più semplice, anche se un po 'restrittiva.

1

Questa domanda era "When is a return type required for methods in Scala?" Una domanda completamente diversa, ma è nello stesso regno di OP.


Questa risposta spiega quando (perché no) si deve dare un tipo di ritorno:

https://stackoverflow.com/a/3127260/2567273

La Chapter 2. Type Less, Do More del libro Programming Scala menzioni:

Quando sono richieste annotazioni di tipo esplicito.

In termini pratici, è necessario fornire le annotazioni di tipo esplicite per le seguenti situazioni:

valori di ritorno Metodo nei seguenti casi:

  • Quando si chiama esplicitamente il ritorno in un metodo (anche a fine).
  • Quando un metodo è ricorsivo.
  • Quando un metodo è sovraccarico e uno dei metodi ne chiama un altro. Il metodo di chiamata ha bisogno di un'annotazione del tipo di ritorno.
  • Quando il tipo di reso indicato è più generico di quanto previsto, ad es. Any.

questo non spiega il motivo per cui è necessario specificare un ritorno (solo quando), ma mi atterrò a quello che ho detto nel mio commento. Il motivo per cui devi specificare un tipo di ritorno quando usi la parola chiave return è perché il compilatore cercherà di dargli un tipo restituito altrimenti inferirà il tipo restituito da solo come se non avessi usato return affatto. Se usi specificamente lo return stai aiutando il compilatore a dirgli cosa restituire e poi si aspetta che tu dica quale tipo stai restituendo.

+0

Non sono sicuro che la giustificazione abbia senso. – acjay

+0

Dal punto di vista di un compilatore, penso che lo faccia. A volte la situazione è troppo complessa per poter dedurre quale sia il tipo di ritorno. Quando non può, devi dirlo. Anche nelle situazioni di base come l'esempio di OP, usando 'return' si crea un contratto che inizia a indicare anche il tipo di reso. Sto solo buttando fuori questa risposta dato quello che so dalla mia classe di compilatori. Non sono un programmatore di scala. – Luminous

+0

Sarebbe un banale passo del compilatore per eliminare un 'ritorno 'non necessario dall'AST. Quindi penso che sarebbe più accurato dire (come fa l'altra risposta) che hanno scelto la coerenza delle regole con il 'return' precoce - l'unico uso necessario di' return' - oltre a fornire un'inferenza per un 'ritorno 'finale non necessario. . – acjay

1

Cosa pensi dovrebbe il tipo di inferenza segnerà il ritorno al tipo di:

def func(n:Int) = { 
    if(n<10) return 23; 
    if(n>10) true else false; 
} 

La prima riga indica il valore di ritorno dovrebbe essere di tipo Int. Ma il ritorno implicito suggerisce un booleano. Quindi diventa abbastanza discutibile su quale dovrebbe essere esattamente il tipo di ritorno. Int, Boolean o Any?

Se non è stato utilizzato il ritorno esplicito, è piuttosto semplice determinare il tipo di funzione restituito. Ma con esso, è un po 'vago e sconosciuto. La soluzione più semplice sarebbe che l'utente specifichi esplicitamente il tipo di reso. Questo rende la vita molto più facile per il compilatore.

Inoltre il team voluto per scoraggiare l'uso di tipi restituiti esplicite, in modo da rendere la gente mette i tipi manuali va con l'intenzione :)

Problemi correlati