2010-07-03 25 views
8

một câu hỏi khác về F #.F # Mã lệnh thi hành

Nếu tôi có đoạn mã sau ...

let ExeC = 
    printfn "c" 
    3 

let ExeB b = 
    printfn "b" 
    2 

let ExeA = 
    printfn "a" 
    1 

printfn "Example %d " ExeA 
printfn "Example %d " (ExeB 1) 
printfn "Example %d " ExeC 

Đầu ra là như sau ...

c 
a 
Example 1 
b 
Example 2 
Example 3 

Những gì có vẻ không bình thường ở đây theo thứ tự mà mã được thực hiện tại là. Trong một câu hỏi trước Brian đã đề cập đến một số thứ về biểu thức, tôi đã hy vọng một người nào đó có thể giải thích thêm một chút nữa. Nó gần như có vẻ như trình biên dịch là thông minh trước khi thực hiện những điều để tính giá trị ... nhưng tôi không biết?

Trả lời

13

ExeAExeC không hoạt động, nhưng chỉ có giá trị. Trình biên dịch đảm bảo rằng giá trị khởi tạo trong thứ tự mà chúng được khai báo trong file nguồn, vì vậy những gì đang xảy ra ở đây là:

  1. ExeC initialises
  2. ExeA initialises
  3. Example 1 được in, sử dụng ExeA 's giá trị được khởi tạo
  4. Chức năng ExeB được gọi là bình thường
  5. Example 3 được in, sử dụng giá trị được khởi tạo ExeC

Nếu bạn muốn ExeAExeC để được thật sự lười biếng - đó là, để kiểm soát khi các tác dụng phụ của họ chạy - bạn có thể biến chúng thành các chức năng mà chấp nhận unit:

let ExeC() = 
    printfn "c" 
    3 

let ExeB b = 
    printfn "b" 
    2 

let ExeA() = 
    printfn "a" 
    1 

printfn "Example %d " (ExeA()) 
printfn "Example %d " (ExeB 1) 
printfn "Example %d " (ExeC()) 
3

Là một tiếp theo theo câu trả lời của Tim, tôi nghĩ bạn có thể đánh giá cao thêm một số thông tin chi tiết về những gì bạn đã gặp phải. Trong ví dụ của bạn, ExeC và ExeA tận dụng lợi thế của phong cách chức năng của tổ chức mã thông qua phạm vi từ vựng và đóng cửa. Hãy để tôi chứng minh một ví dụ mạnh mẽ hơn.

let calc n = 
    //... 
    let timesPieDiv4 = 
     let pie = 3.14 
     let pieDiv4 = pie/4. 
     n * pieDiv4 

    //... 

đây một lần nữa timesPieDiv4 không phải là một chức năng, nhưng không có một cơ thể, trong đó có một loạt các tính toán phụ mà không được tiếp xúc với phần còn lại của calc chức năng. Trong một ngôn ngữ như C#, bạn có hai tùy chọn mà cả hai đều không hấp dẫn tôi. Tùy chọn đầu tiên là chỉ cần khai báo piepieDiv4 trong phần chính của calc, nhưng sau đó ít rõ ràng hơn cách chúng được sử dụng và bạn làm bẩn không gian biến của mình. Tùy chọn khác là để tính các tính toán phụ đó ra thành một hàm trợ giúp riêng riêng biệt. Nhưng tôi không thích các chức năng như vậy, bởi vì với rất nhiều khó khăn trong việc phân tích các thuật toán phức tạp của bạn vì bạn thường xuyên tìm kiếm các phần triển khai khác nhau. Cộng với đó là rất nhiều mã tấm nồi hơi và giá trị đi qua. Đó là lý do tại sao chức năng F # là "công khai" theo mặc định, phạm vi từ vựng và đóng cửa cho phép bạn sắp xếp theo thứ bậc các hàm và giá trị "riêng tư" trong các hàm công khai của bạn.

+0

Cảm ơn Stephen - đánh giá cao việc xây dựng thêm! –

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