2011-09-23 38 views
9

Có mã như"let() =" có nghĩa là gì trong Ocaml?

let() = print_string "something" in 
fn 

ở một số mã OCaml.

Điều này có nghĩa là gì? Có ý nghĩa đặc biệt nào về "()" không? hoặc là nó cùng một ý nghĩa như

print_string "something"; 
fn 
+0

Có thể bạn sẽ muốn sử dụng 'let _ = ...' độc quyền vì nó sẽ hoạt động tốt nhất nếu không phải tất cả các biểu thức. –

+1

'cho phép _ = ...' hoặc kết hợp mẫu dễ vỡ, hoàn toàn không được khuyến nghị. Nó khá giống với việc đưa ngón giữa vào hệ thống kiểu. – nlucaroni

+0

Tôi đồng ý với nlucaroni. nếu bạn muốn 'let _ = ... in ...', thì bạn có thể muốn 'bỏ qua (...); ... ' – newacct

Trả lời

11

Không có gì đặc biệt về () trong biểu let này là, nó chỉ là một mô hình. Tất cả let biểu thức trông giống như letpattern=expressioninother-expression. Ở đây, mẫu sẽ luôn khớp nhau, bởi vì print_string trả về unit() là giá trị duy nhất của loại đó. Bằng cách này, nó chỉ là một cách khác để kết hợp hai biểu thức thành một khi biểu thức đầu tiên thực sự là một câu lệnh (trả về unit).

Vì vậy, bạn nói đúng, cấu trúc có ý nghĩa khá giống với việc sử dụng toán tử ;. Sự khác biệt thực sự duy nhất là ưu tiên. Nếu, ví dụ, bạn viết

if x < 3 then 
    print_string "something"; 
    f x 

bạn sẽ thấy rằng f xluôn gọi. Mức độ ưu tiên của ; quá thấp để kéo biểu thức thứ hai dưới sự kiểm soát của if. Đó là lý do mà nhiều người (kể cả tôi) có thói quen sử dụng let() =expression. Nếu bạn viết ở trên như

if x < 3 then 
    let() = print_string "something" 
    in f x 

các f x chỉ gọi khi x là ít hơn 3, mà thường là những gì tôi muốn. Về bản chất, mức độ ưu tiên của let cao hơn nhiều so với ;. Tất nhiên có những cách khác để có được hiệu ứng này, nhưng điều tốt đẹp về việc sử dụng let là bạn không phải thêm bất cứ điều gì sau này trong mã (giống như dấu đóng ngoặc đơn hoặc end). Nếu bạn đang thêm print_string làm tuyên bố gỡ lỗi, đây là cách tiện dụng để giữ các thay đổi cục bộ tại một điểm.

+0

Như một ví dụ khác về chương trình đáng ngạc nhiên cho phép bởi cú pháp, nếu bạn chỉ muốn thực hiện' f() 'khi luật thông thường giữ số học, bạn có thể viết 'let 4 = 2 + 2 in f(); ; ' –

3

câu trả lời Jeffrey là hoàn toàn chính xác, nhưng thêm một điểm:

nếu bạn viết

fx "something"; 
fn 

Và bạn sai lầm loại kết quả của fx "something" trình biên dịch sẽ phát ra một cảnh báo, có thể bị lạc trong biên dịch. Mặt khác nếu bạn viết:

let() = fx "something" in 
fn 

Trình biên dịch sẽ gõ kiểm tra xem kết quả của fx "something" có thể được kết hợp với (), ví dụ rằng nó thực sự của loại unit là. Vì vậy, nếu bạn sai lầm một lỗi được sản xuất, mà thường là an toàn hơn.

Ngoài ra còn có khả năng viết

let _ = fx "something" in 
fn 

mà sẽ chỉ nhận được tác dụng ưu tiên mà Jeffrey đã đề cập, nhưng không phải làm bất cứ việc kiểm tra loại, kể từ _ có thể được kết hợp với các giá trị của bất kỳ loại.

+0

và cái cuối cùng tương đương với 'ignore (fx" something "); fn' trong ký hiệu dấu chấm phẩy – newacct