Tôi mới bắt đầu học F #. Cuốn sách sử dụng các ký hiệu sau:Ký hiệu '()' này có nghĩa là gì?
let name() = 3
name()
gì khác với điều này:
let name = 3
name
?
Tôi mới bắt đầu học F #. Cuốn sách sử dụng các ký hiệu sau:Ký hiệu '()' này có nghĩa là gì?
let name() = 3
name()
gì khác với điều này:
let name = 3
name
?
Trước khi trả lời những gì ()
cho phép nhận được một số khái niệm cơ bản được xác định và một số ví dụ được thực hiện.
Trong F # a let statement có tên, không hoặc nhiều đối số và biểu thức.
Để đơn giản hóa chúng tôi sẽ thực hiện:
Nếu không có đối số thì tuyên bố let là value.
Nếu có đối số thì câu lệnh let là function.
Đối với một giá trị, kết quả của biểu thức chỉ được đánh giá một lần và được liên kết với số nhận dạng; nó là bất biến.
Đối với một hàm, biểu thức được đánh giá mỗi lần hàm được gọi.
Vì vậy, đây giá trị
let a = System.DateTime.Now;;
sẽ luôn có thời gian khi nó lần đầu tiên được đánh giá hay muộn gọi, tức là
a;;
val it : System.DateTime = 1/10/2017 8:16:16 AM ...
a;;
val it : System.DateTime = 1/10/2017 8:16:16 AM ...
a;;
val it : System.DateTime = 1/10/2017 8:16:16 AM ...
và chức năng này
let b() = System.DateTime.Now;;
sẽ alwa y có thời gian mới mỗi khi được đánh giá, tức là
b();;
val it : System.DateTime = 1/10/2017 8:18:41 AM ...
b();;
val it : System.DateTime = 1/10/2017 8:18:49 AM ...
b();;
val it : System.DateTime = 1/10/2017 8:20:32 AM ...
Bây giờ để giải thích ý nghĩa của ()
. Lưu ý rằng System.DateTime.Now
không cần đối số để hoạt động.
Làm cách nào để tạo hàm khi biểu thức không cần đối số?
Mọi đối số đều phải có loại, vì vậy F # có unit type cho các hàm không cần đối số và giá trị duy nhất cho loại đơn vị là ()
.
Vì vậy, đây là một chức năng với một đối số x
loại int
let c x = x + 1;;
và đây là một chức năng với một đối số ()
loại unit
let b() = System.DateTime.Now;;
Sử dụng ()
tạo hàm có tham số loại unit
, thay vì trường hợp thứ hai chỉ là một số nguyên đơn giản.
Điều này đặc biệt quan trọng khi bạn muốn kiểm soát việc thực hiện chức năng.
Sự khác biệt chính là khi bạn có
let name() =
printfn "hello"
1
vs
let name =
printfn "hello"
1
sau đó
let t = name + name
sẽ in "hello" một lần. Nhưng
let t = (name()) + (name())
sẽ in "hello" hai lần.
Bạn phải cẩn thận với điều này khi xem xét thứ tự các hàm được đánh giá.
Hãy xem xét các chương trình sau đây:
let intversion =
printfn "creating integer constant"
1
printfn "integer created"
let funcversion() =
printfn "executing function"
1
printfn "function created"
let a = intversion + intversion
printfn "integer calculation done"
let b = (funcversion()) + (funcveriosn())
printfn "function calculation done"
này sẽ in ra sau theo thứ tự
Tôi nghĩ tôi cần thêm ví dụ. Nó không quá rõ ràng tại sao nó lại quan trọng đến vậy. Dù sao, cái đó là cái gì? – Fabricio
Tôi sẽ thêm một số ví dụ khác. Các '; 1' chúng ta tương đương với một dòng mới và sau đó là 1 để có một giá trị trả về. Tôi chỉ cần đặt nó trong ngắn gọn –
Tôi không có lý do tại sao '" tạo hằng số nguyên "' được in nếu nó chỉ được xác định. – Fabricio
Trong
let name() = 3
name()
name
là một chức năng, kiểu unit -> int
.
Trong
let name = 3
name
name
là một số nguyên, kiểu int
.
Trong F #, mọi chức năng đều có kiểu đầu vào và loại đầu ra. Kiểu đầu vào của let name() = 3
là unit
, chỉ có một giá trị ()
.Loại đầu ra của nó là int
, có giá trị từ –2,147,483,648
đến 2,147,483,647
. Như một loại ví dụ khác bool
chỉ có hai giá trị, true
và false
.
Vì vậy, hãy trả lời câu hỏi về cách sử dụng của ()
. Nếu bạn không chỉ định giá trị đầu vào của một hàm, nó không thể được thực thi. Vì vậy, bạn phải chỉ định một giá trị đầu vào cho hàm let name()=3
của bạn để thực hiện nó và vì kiểu đầu vào của nó là unit
, giá trị duy nhất bạn có thể sử dụng là ()
.
Đây là một cách khác để xác định chức năng và tên:
let name : (unit -> int) = (fun _ -> 3);;
và so sánh này để:
let name : int = 3
Nice, cảm ơn! Upvote này cung cấp cho bạn đại diện 10k. :) – Vache
chắc chắn không nghĩ về ()
như một số cú pháp cho một cuộc gọi chức năng hoặc bất cứ điều gì như thế . Nó chỉ là một giá trị, như 3, 5, 'q', sai, hoặc "blah". Giá trị này là một giá trị của loại Unit
và trên thực tế nó chỉ là giá trị đơn vị loại của đơn vị loại, nhưng thực sự là bên cạnh điểm. ()
ở đây là chỉ một giá trị. Tôi không thể nhấn mạnh điều đó.
Đầu tiên xem xét
let name x = 3
này là gì? Điều này chỉ định nghĩa một hàm trên x, trong đó x có thể là bất kỳ kiểu nào. Trong C# đó sẽ là:
int Name<T>(T x)
{
return 3;
}
Bây giờ nếu chúng ta nhìn vào let name() = 3
(và tôi hơi khuyên bạn nên đặt không gian thêm đó, vì vậy nó làm cho ()
tìm một giá trị hơn một số cấu trúc cú pháp) sau đó trong C# bạn có thể nghĩ nó như một cái gì đó tương tự (giả)
int Name<T>(T x) where T == Unit //since "()" is the only possible value of Unit
{
return 3;
}
hay đơn giản hơn
int Name(Unit x)
{
return 3;
}
vì vậy, chúng ta thấy rằng tất cả let name() = 3
là, định nghĩa về af unction có một đối số Unit
và trả về 3, giống như phiên bản C# ở trên.
Tuy nhiên, nếu chúng tôi xem xét let name = 3
thì đó chỉ là định nghĩa biến, giống như var name = 3
trong C#.
Đơn giản chỉ cần đặt, nó chỉ là một hình thức F # chức năng gọi mà không có tham số? – Fabricio
@Fabricio Có. Nhưng tôi đã thêm một cái gì đó để vượt qua tối thiểu 15 ký tự cho một bình luận. –
@Fabricio: Tôi sẽ không nói điều đó. 'b' ở đây là một hàm nhận tham số * one *:' unit'. Nếu bạn cố gắng gọi nó mà không có dấu ngoặc đơn, bạn sẽ nhận được * giá trị hàm * 'b' thay vì kết quả * của hàm' b' *. Hãy thử 'let d = b ;; d() ;; 'trong FSI. –