2013-07-10 13 views
8

Mam następujący F # program:Different zachowanie na F modułu # inicjalizacji

open MyModule 

printfn "%d" test 

Z mymodule samopoczucie:

module MyModule 

printfn "foo" 

let test = 
    printfn "bar" 
    42 

To daje następujący wynik:

foo 
bar 
42 

Kiedy zmienić Mój moduł do:

module MyModule 

printfn "foo" 

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

... wynik jest:

42 

Dlaczego nie "foo" wydrukowany więcej?

Odpowiedz

17

Myślę, że sekcja 12.5.1 specyfikacji, Execution of Static Initializers, ma twoją odpowiedź. Cytowanie odpowiednich bitów:

statycznego inicjatora do pliku jest wykonywane przy pierwszym dostępie wartości, która ma zauważalnego inicjalizacji

i

Wszystkie definicje mają zauważalnego inicjalizacji z wyjątkiem dla następujące definicje w modułach:

Poniższa lista obejmuje:

wartości

dla zmienny, nie nagwintowanych lokalnego, które są związane z prostym stałej ekspresji

Po zakomentowałeś pierwszą linię test, staje się stała ekspresja. Dlatego też nie uruchamia już statycznej inicjalizacji.

EDIT

Spec nie dostarcza uzasadnienia dla takiego zachowania, ale jest podobny do C# 's. Na przykład w tym kodzie inicjalizacja statyczna nigdy nie występuje:

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

Dziękuję, po przeczytaniu go kilka razy rozumiem. Chociaż zachowanie wydaje się zbyt skomplikowane/niekonsekwentne. Na przykład "let test = 1 + 2" nie drukuje "foo", podczas gdy "let test = add 1 2" z add jest "dodaj b = a + b" drukuje "foo". Jest to zgodne ze specyfikacją językową, ale nadal wydaje się dziwne. Czy istnieje powód, dla którego inicjatory statyczne nie są wykonywane po pierwszym dostępie do dowolnego elementu modułu, bez względu na to, czy jest to proste wyrażenie stałe, czy coś innego? – stmax

+0

Zaktualizowałem swoją odpowiedź, aby zademonstrować, że C# zachowuje się podobnie. Przypuszczam, że może to być optymalizacja wydajności. Ponieważ niemożliwe jest, aby stała była zależna od efektów ubocznych lub jakiegokolwiek obliczenia, nie ma wyraźnego powodu inicjalizacji statycznej przed uzyskaniem dostępu do niej. – Daniel

Powiązane problemy