2013-07-10 10 views
8

Ho il seguente programma F #:comportamento differente su F inizializzazione # modulo

open MyModule 

printfn "%d" test 

Con MyModule essere:

module MyModule 

printfn "foo" 

let test = 
    printfn "bar" 
    42 

Questo produce il seguente output:

foo 
bar 
42 

Quando cambio MyModule a:

module MyModule 

printfn "foo" 

let test = 
    // printfn "bar" <-- note the comment! 
    42 

... il risultato è:

42 

Perché non "pippo" Get più stampato?

risposta

17

Penso che la sezione 12.5.1 della specifica, Execution of Static Initializers, abbia la tua risposta. Citando corrispondenti bit:

l'inizializzatore statico per il file è eseguito al primo accesso di un valore che ha inizializzazione osservabile

e

Tutte le definizioni hanno inizializzazione osservabili tranne per il seguenti definizioni nei moduli:

L'elenco che segue include:

valori

non mutevole, non-thread-locale che sono associati a una semplice espressione costante

Dopo commentando la prima linea di test, diventa un'espressione costante. Pertanto, non attiva più l'inizializzazione statica.

EDIT

Le specifiche non fornisce la motivazione per questo comportamento, ma è simile a C# 's. Ad esempio, in questo codice l'inizializzazione statica non si verifica mai:

class Program { 
    static void Main(string[] args) { 
     Console.WriteLine(T.Integer); 
     Console.WriteLine(T.Null); 
     Console.WriteLine(T.Enum); 
     Console.Read(); 
    } 
} 

static class T { 
    static T() { 
     Console.WriteLine("You won't see this."); 
    } 
    public const int Integer = 1; 
    public const string Null = null; 
    public const ConsoleKey Enum = ConsoleKey.Escape; 
} 
+0

Grazie, dopo averlo letto alcune volte capisco. Anche se il comportamento sembra troppo complicato/incoerente. Ad esempio "let test = 1 + 2" non stampa "pippo", mentre "let test = aggiungi 1 2" con l'aggiunta di "lascia aggiungere b = a + b" stampa "pippo". Questo è conforme alle specifiche del linguaggio, ma sembra ancora strano. C'è un motivo per cui gli inizializzatori statici non vengono solo eseguiti al primo accesso a qualsiasi cosa all'interno del modulo, non importa se si tratta di una semplice espressione costante o qualcos'altro? – stmax

+0

Ho aggiornato la mia risposta per dimostrare che C# si comporta in modo simile. Suppongo che potrebbe essere un ottimizzazione delle prestazioni. Poiché è impossibile che una costante dipenda dagli effetti collaterali o da qualsiasi calcolo, non c'è alcun motivo apparente per l'inizializzazione statica prima dell'accesso. – Daniel

Problemi correlati