2009-04-29 4 views
19

Sto lavorando per imparare Scala - proveniente da uno sfondo C++. Sto cercando di scrivere una piccola classe per un'applicazione di tracciamento delle attività che sto hackerando insieme a aiutami ad imparare come programmare Scala.Utilizzare le variabili di classe come costanti in Scala

Questo sembra come se dovrebbe essere semplice, ma per qualche motivo mi sta sfuggendo:

package com.catenacci.tts 

class Task(val ID:Int, val Description:String) { 
val EmptyID = 0 
val EmptyDescription = "No Description" 

def this() = this(EmptyID,EmptyDescription) 
def this(ID:Int)={ 
    this(ID,EmptyDescription) 
} 
def this(Description:String)={ 
    this(EmptyID,Description) 
} 
} 

Sto cercando di fornire tre costruttori: Task (ID, descrizione), Task (ID), Task (Descrizione). Negli ultimi 2 casi, voglio inizializzare i valori su valori costanti se uno dei valori non è fornito dal chiamante. E voglio essere in grado di controllare questo fuori della classe per scopi di test unitari. Quindi ho pensato di inserire due valenze pubbliche mi permettesse di controllare da fuori della classe per rendere sicuro che il mio stato è quello che mi aspetto.

Tuttavia, per qualche motivo questo codice non verrà compilato. Ottengo il seguente errore:

error: not found: value EmptyID 

e

error: not found: value EmptyDescription 

Allora, cosa mi manca? Sto lavorando a "Programming in Scala" quindi se c'è una risposta semplice a questa domanda, per favore dammi i numeri di pagina . Non mi interessa leggere ma passare il codice a pagina 60 e pagina 62, non riesco a capire perché questo codice non funziona.

Immagino che abbia qualcosa a che fare con il fatto che si tratta di metodi di costruzione e che probabilmente i due val non sono inizializzati fino alla fine dei costruttori. Se questo è il caso c'è qualche modo per ottenere l'effetto che sto cercando?

+1

Vedere anche SIP 23 o '42.type': http://stackoverflow.com/a/39065260/6309 – VonC

risposta

38

È possibile definire le costanti in un oggetto associato:

object Task { 
val EmptyID = 0 
val EmptyDescription = "No Description" 
} 

E poi farvi riferimento come Task.EmptyID e Task.EmptyDescription.

Penso che Scala 2.8 supporti i valori predefiniti.

8

Vedere Germán per la risposta. Ciò accade perché un costruttore è tecnicamente parte dell'ambito statico. In altre parole, il costruttore non può accedere a nessun membro di istanza perché l'istanza non è stata ancora creata. Tutti i "membri della classe" sono in realtà membri di istanze, motivo per cui il codice nella domanda non funziona. La risposta di Germán risolve questo spostando i due valori rilevanti nell'oggetto associato, il che li rende in effetti membri statici della classe Task (non proprio, ma si può pensare in questo modo).

+0

Grazie - è bello sapere perché questo non ha funzionato bene e sapere come risolverlo. –

+0

Sì. Per un po 'mi stavo chiedendo perché questo non fosse un problema in Java con il classico "public static final" - è a causa della staticità. –

1

In "Programmazione in Scala", vedere la sezione 6.7 dove viene spiegata la concatenazione delle chiamate del costruttore. Il costruttore principale è descritto come "il singolo punto di ingresso di una classe".