2011-09-03 8 views
19

Il linguaggio Scala richiede di inizializzare la variabile di istanza prima di utilizzarla. Tuttavia, Scala non fornisce un valore predefinito per la variabile. Al contrario, è necessario impostare il valore manualmente utilizzando la sottolineatura carattere jolly, che agisce come un valore predefinito, come seguePerché il linguaggio Scala richiede di inizializzare una variabile di istanza invece di basarsi su un valore predefinito?

var name:String = _ 

Lo so, lo so ... posso definire un costruttore nella definizione della classe, che prende come parametro nostra variabile esempio, così Scala non forzare la sua inizializzazione, come illustrato di seguito

class Person(var name:String) 

Tuttavia, devo dichiarare nel corpo perché ho bisogno di usare un'annotazione Java cui ElementType è campo o il metodo; cioè, può essere semplicemente applicato a una variabile di istanza o al metodo dichiarato nel corpo della nostra classe.

Domanda: Perché il linguaggio Scala richiede di inizializzare una variabile di istanza, che si tratti di un valore predefinito _ o di qualsiasi cosa desideri, dichiarata nel corpo di una classe anziché fare affidamento su un valore predefinito?

+2

La preferenza di Martin sarebbe la mia ipotesi :-) Per lo meno è esplicito e gli extra 2 caratteri (4 con spazi) non sono terribilmente scoraggianti. Sembra quasi assurdo che Java (un linguaggio * molto verboso) lasci omettere il compito. Inoltre, sembra fuorviante affermare che gli "argomenti del costruttore" (non so come si chiamino realmente: - /) non siano forzati per essere inizializzati - lo sono sicuramente quando l'oggetto viene istanziato. –

risposta

6

È possibile applicare l'annotazione quando lo si specifica come argomento costruttore. Inoltre, potrebbe essere necessario utilizzare una meta-annotazione per limitare il target a cui viene applicata l'annotazione - vedi http://www.scala-lang.org/api/2.10.2-RC2/index.html#scala.annotation.meta.package

La tua domanda su "fare affidamento su un valore predefinito" è in qualche modo poco chiara, comunque. L'inizializzazione utilizzando un carattere di sottolineatura corrisponde all'assegnazione del valore della variabile a null. A quale altra impostazione predefinita stai pensando?

+0

So che il segno di sottolineatura è usato per assegnare un valore predefinito. Tuttavia, voglio sapere perché Scala non consente qualcosa come il nome var: String (senza assegnazione underscore) invece quando dichiarato nel corpo della classe. Hai evidenziato una bella funzionalità di Scala (+1) che non conoscevo. Tuttavia, non soddisfa i miei bisogni perché ho anche bisogno di un costruttore no-arg che viene sovrascritto se dichiaro le mie variabili di istanza in un costruttore dichiarato nella definizione della classe –

+4

Il motivo per cui l'assegnazione è richiesta è, credo, in modo che il compilatore può distinguere tra una var astratta (che è compilata in una coppia di metodi astratti) e una var concreta, che richiede anche che il campo sia generato nel file di classe. –

4

Scala non ha alcun problema con "var name: String" nel corpo della classe. Hai provato? Non significa quello che vuoi che significhi, comunque. È una varietà astratta.

abstract class A { 
    var name: String 
} 
// some possible uses for abstract vars 
trait B { type T ; var name: T } 
class B1 extends B { type T = Int ; var name: Int = 5 } 
// hey, no storage 
class B2 extends B { type T = String ; def name = "abc" ; def name_=(x: String) =() } 
+0

Se solo dichiaro var name: String; quando compilato in un file .class, il compilatore Scala si lamenterà: il nome della variabile non è definito. Quindi mi piacerebbe sapere, anche a causa di problemi di progettazione, perché Scala non permette di usare var name: String nel corpo della classe senza dichiararne il valore iniziale; sia esso un valore predefinito o qualsiasi altra cosa –

+1

Potresti rileggere la mia risposta, che sembra aver ignorato. Stai chiedendo perché esiste "astratto"? Un membro astratto non implementato significa che non puoi istanziare la classe. Questo è di progettazione, proprio come in Java. – extempore

18

Se si utilizza il codice come il seguente si dichiara, che il name dovrebbe essere astratto:

class A { 
    var name: String 
} 

Suppongo che si sapeva già che. Quindi la tua domanda è piuttosto di natura sintattica. La risposta è la coerenza con altri possibili candidati astratti.

si supponga di voler fare qualcosa di simile:

class A { 
    var variable: String = _ // variable has some default value (probably null) 
    val value: String = _ // value cannot have any default values, since it cannot be reassigned later. 
    def method: String = _ // method could return some default value (probably null) 
    type theType = _ // what should the default type be? (Any perhaps?) 
} 

Gli ultimi tre esempi non hanno nemmeno compilare. Ora supponiamo che si vuole fare qualcosa di simile:

class A { 
    var variable: String 
    val value: String 
    def method: String 
    type theType 
} 

Dal mio punto di vista, anche qualcuno che capisce a malapena Scala vede solo dichiarazioni. Non c'è modo di interpretarli male, perché non c'è niente altro che dichiarazioni. La sola e unica confusione sorge quando vieni da un'altra lingua e supponi per un secondo che ci siano alcuni valori predefiniti. Ma questa confusione è scomparsa non appena vedi il primo esempio (quello con i valori predefiniti). E se la tua classe deve far parte di una gerarchia astratta per poter dichiarare membri astratti, quindi anche se sei nuovo nella lingua, hai già qualche aiuto in più dal compilatore.

Spero che questo risponda alla tua domanda e alla felice codifica.

+1

Grazie per la risposta (+1) –

Problemi correlati