2012-01-31 8 views
18

Ho qualche codice:Scala App val di inizializzazione nel metodo main

object Main extends App 
{ 
    val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r 

    override def main (args:Array[String]) 
    { 
     // Why is NameTemplate null here? 
    } 
} 

Perché NameTemplate non inizializzato all'interno del metodo principale?

risposta

17

Se si utilizza App tratto, quindi non è necessario eseguire l'override main metodo - basta scrivere il codice nel corpo del object:

object Main extends App { 
    val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r 

    println(NameTemplate) 

    val NameTemplate(name, version) = args(0) 

    println(name + " v" + version) 

} 

Funziona perché App tratto si estende DelayedInit tratto che ha procedura di inizializzazione molto speciale. Puoi anche accedere agli argomenti con args, come mostrato nell'esempio.

Hai ancora bisogno di scrivere main metodo se non si desidera estendere App, ma in questo caso funzionerà come previsto:

object Main { 
    val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r 

    def main(args: Array[String]) { 
     println(NameTemplate) 

     val NameTemplate(name, version) = args(0) 

     println(name + " v" + version) 
    } 

} 
6

Il DelayedInit tratto (che si estende App) provoca la riscrittura di intialisation codice da eseguire all'interno di un metodo speciale delayedInit(). Questo sarebbe quindi normalmente invocato da main. Poiché si sta eseguendo l'override di main, tuttavia, il codice delayedInit() non viene mai richiamato e pertanto il valore non viene inizializzato.

Come spiega @tenshi, è possibile aggirare il problema non estendendo App o spostando il codice principale nel corpo dell'oggetto Main.