2013-07-10 23 views
8

Tôi có F # chương trình sau đây:hành vi khác nhau trên F # mô-đun khởi

open MyModule 

printfn "%d" test 

Với MyModule phúc:

module MyModule 

printfn "foo" 

let test = 
    printfn "bar" 
    42 

này tạo ra kết quả như sau:

foo 
bar 
42 

Khi tôi thay đổi MyModule đến:

module MyModule 

printfn "foo" 

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

... kết quả là:

42 

Tại sao không "foo" được in nữa?

Trả lời

17

Tôi nghĩ mục 12.5.1 của thông số kỹ thuật, Execution of Static Initializers, có câu trả lời của bạn. Trích dẫn các bit có liên quan:

initializer tĩnh cho các tập tin được thực thi trên truy cập đầu tiên của một giá trị mà có khởi quan sát

Tất cả các định nghĩa có khởi quan sát được ngoại trừ các định nghĩa sau trong mô-đun:

Danh sách sau bao gồm:

giá trị

không thể thay đổi, không thread-địa phương được ràng buộc với một biểu thức hằng số đơn giản

Sau khi cho ý kiến ​​ra dòng đầu tiên của test, nó trở thành một biểu thức hằng số. Do đó, nó không còn kích hoạt khởi tạo tĩnh nữa.

EDIT

Các spec không cung cấp cơ sở lý luận cho hành vi này, nhưng nó tương tự như C# 's. Ví dụ: trong mã này, việc khởi tạo tĩnh không bao giờ xảy ra:

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

Cảm ơn, sau khi đọc nó một vài lần tôi hiểu nó. Mặc dù hành vi có vẻ quá phức tạp/không nhất quán. Ví dụ: "let test = 1 + 2" không in "foo", trong khi "let test = add 1 2" có thêm "let add a b = a + b" in print "foo". Điều này phù hợp với đặc tả ngôn ngữ nhưng vẫn có vẻ lạ. Có một lý do tại sao initializers tĩnh không chỉ thực hiện trên truy cập đầu tiên vào bất cứ điều gì trong module, không có vấn đề nếu nó là một biểu thức liên tục đơn giản hoặc cái gì khác? – stmax

+0

Tôi đã cập nhật câu trả lời của mình để chứng minh rằng C# hoạt động tương tự. Tôi cho rằng nó có thể là một tối ưu hóa hiệu suất. Vì không thể cho một hằng số phụ thuộc vào các tác dụng phụ, hoặc bất kỳ tính toán nào cho vấn đề đó, không có lý do rõ ràng nào để khởi tạo tĩnh xảy ra trước khi truy cập nó. – Daniel

Các vấn đề liên quan