F # - Hướng dẫn nhanh

F # là một ngôn ngữ lập trình chức năng. Để hiểu các cấu trúc F #, bạn cần đọc vài dòng về mô hình lập trình có tênFunctional Programming.

Lập trình hàm xử lý các chương trình máy tính như các hàm toán học. Trong lập trình hàm, trọng tâm sẽ là hằng số và hàm, thay vì các biến và trạng thái. Vì hàm và hằng là những thứ không thay đổi.

Trong lập trình chức năng, bạn sẽ viết các chương trình mô-đun, tức là, các chương trình sẽ bao gồm các chức năng sẽ lấy các chức năng khác làm đầu vào.

Các chương trình được viết bằng ngôn ngữ lập trình chức năng có xu hướng ngắn gọn.

Về F #

Sau đây là những thông tin cơ bản về F # -

  • Nó được phát triển vào năm 2005 tại Microsoft Research.
  • Nó là một phần của họ ngôn ngữ .Net của Microsoft.
  • Nó là một ngôn ngữ lập trình chức năng.
  • Nó dựa trên ngôn ngữ lập trình chức năng OCaml.

Đặc điểm của F #

  • Đó là .Net triển khai OCaml.

  • Nó biên dịch mã byte .Net CLI (Giao diện ngôn ngữ chung) hoặc MSIL (Ngôn ngữ trung gian của Microsoft) chạy trên CLR (Thời gian chạy ngôn ngữ chung).

  • Nó cung cấp kiểu suy luận.

  • Nó cung cấp các cấu trúc đối sánh mẫu phong phú.

  • Nó có khả năng viết mã và gỡ lỗi tương tác.

  • Nó cho phép viết các hàm bậc cao hơn.

  • Nó cung cấp mô hình đối tượng được phát triển tốt.

Sử dụng F #

F # thường được sử dụng trong các lĩnh vực sau:

  • Làm mô hình khoa học
  • Giải quyết vấn đề toán học
  • Công việc nghiên cứu trí tuệ nhân tạo
  • Mô hình tài chính
  • Thiết kế đồ họa
  • Thiết kế CPU
  • Lập trình biên dịch
  • Telecommunications

Nó cũng được sử dụng trong các ứng dụng CRUD, trang web, trò chơi GUI và các chương trình mục đích chung khác.

Các công cụ cần thiết cho lập trình F # được thảo luận trong chương này.

Môi trường phát triển tích hợp (IDE) cho F #

Microsoft cung cấp Visual Studio 2013 để lập trình F #.

Visual Studio 2013 Community Edition miễn phí có sẵn từ trang web chính thức của Microsoft. Cộng đồng Visual Studio 2013 trở lên đi kèm với Công cụ Visual F #. Chi tiết cài đặt có sẵn tại Hướng dẫn Asp.net .Công cụ Visual F # bao gồm trình biên dịch dòng lệnh (fsc.exe) và F # Interactive (fsi.exe).

Sử dụng các công cụ này, bạn có thể viết tất cả các loại chương trình F # từ các ứng dụng dòng lệnh đơn giản đến các ứng dụng phức tạp hơn. Bạn cũng có thể viết các tệp mã nguồn F # bằng trình soạn thảo văn bản cơ bản, như Notepad, và biên dịch mã thành các tập hợp bằng trình biên dịch dòng lệnh.

Bạn có thể tải xuống từ Microsoft Visual Studio. Nó được cài đặt tự động trong máy của bạn.

Viết chương trình F # trên liên kết

Vui lòng truy cập trang web chính thức của F # để có hướng dẫn mới nhất về cách tải các công cụ dưới dạng gói Debian hoặc biên dịch chúng trực tiếp từ nguồn - https://fsharp.org/use/linux/.

F # là một ngôn ngữ lập trình chức năng.

Trong F #, các hàm hoạt động giống như kiểu dữ liệu. Bạn có thể khai báo và sử dụng một hàm theo cách tương tự như bất kỳ biến nào khác.

Nói chung, một ứng dụng F # không có bất kỳ điểm đầu vào cụ thể nào. Trình biên dịch thực thi tất cả các câu lệnh cấp cao nhất trong tệp từ trên xuống dưới.

Tuy nhiên, để tuân theo phong cách lập trình thủ tục, nhiều ứng dụng giữ một câu lệnh cấp cao nhất gọi vòng lặp chính.

Đoạn mã sau đây cho thấy một chương trình F # đơn giản:

open System
(* This is a multi-line comment *)
// This is a single-line comment

let sign num =
   if num > 0 then "positive"
   elif num < 0 then "negative"
   else "zero"

let main() =
   Console.WriteLine("sign 5: {0}", (sign 5))

main()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

sign 5: positive

Xin lưu ý rằng -

  • Tệp mã F # có thể bắt đầu bằng một số open câu lệnh được sử dụng để nhập không gian tên.

  • Phần thân của tệp bao gồm các chức năng khác thực hiện logic nghiệp vụ của ứng dụng.

  • Vòng lặp chính chứa các câu lệnh thực thi hàng đầu.

Bạn đã thấy cấu trúc cơ bản của một chương trình F #, vì vậy sẽ dễ dàng hiểu được các khối xây dựng cơ bản khác của ngôn ngữ lập trình F #.

Mã thông báo trong F #

Một chương trình F # bao gồm các mã thông báo khác nhau. Mã thông báo có thể là một từ khóa, một số nhận dạng, một hằng số, một chuỗi ký tự hoặc một ký hiệu. Chúng tôi có thể phân loại mã thông báo F # thành hai loại:

  • Keywords
  • Ký hiệu và toán tử

F # Từ khóa

Bảng sau đây cho thấy các từ khóa và mô tả ngắn gọn về các từ khóa. Chúng ta sẽ thảo luận về việc sử dụng các từ khóa này trong các chương tiếp theo.

Từ khóa Sự miêu tả
abstract Chỉ ra một phương thức không có triển khai trong kiểu mà nó được khai báo hoặc là ảo và có một triển khai mặc định.
and Được sử dụng trong các ràng buộc đệ quy lẫn nhau, trong khai báo thuộc tính và với nhiều ràng buộc về các tham số chung.
as Được sử dụng để cung cấp cho đối tượng lớp hiện tại một tên đối tượng. Cũng được sử dụng để đặt tên cho toàn bộ mẫu trong khớp mẫu.
assert Được sử dụng để xác minh mã trong quá trình gỡ lỗi.
base Được sử dụng làm tên của đối tượng lớp cơ sở.
begin Trong cú pháp dài dòng, chỉ ra điểm bắt đầu của một khối mã.
class Trong cú pháp dài dòng, chỉ ra sự bắt đầu của một định nghĩa lớp.
default Chỉ ra việc thực hiện một phương thức trừu tượng; được sử dụng cùng với khai báo phương thức trừu tượng để tạo phương thức ảo.
delegate Dùng để khai báo một đại biểu.
do Được sử dụng trong các cấu trúc lặp hoặc để thực thi mã mệnh lệnh.
done Trong cú pháp dài dòng, chỉ ra phần cuối của một khối mã trong một biểu thức lặp.
downcast Được sử dụng để chuyển đổi sang một loại thấp hơn trong chuỗi kế thừa.
downto Trong một for biểu thức, được sử dụng khi đếm ngược lại.
elif Được sử dụng trong phân nhánh có điều kiện. Một dạng rút gọn của else if.
else Được sử dụng trong phân nhánh có điều kiện.
end

Trong định nghĩa kiểu và phần mở rộng kiểu, chỉ ra phần cuối của phần định nghĩa thành viên.

Trong cú pháp dài dòng, được sử dụng để chỉ định phần cuối của khối mã bắt đầu bằng từ khóa begin.

exception Dùng để khai báo một kiểu ngoại lệ.
extern Chỉ ra rằng một phần tử chương trình đã khai báo được định nghĩa trong một hệ nhị phân hoặc hợp ngữ khác.
false Được sử dụng như một nghĩa đen Boolean.
finally Được sử dụng cùng với việc cố gắng giới thiệu một khối mã thực thi bất kể trường hợp ngoại lệ có xảy ra hay không.
for Được sử dụng trong các cấu trúc lặp.
fun Được sử dụng trong biểu thức lambda, còn được gọi là hàm ẩn danh.
function Được sử dụng như một sự thay thế ngắn hơn cho từ khóa fun và một biểu thức đối sánh trong một biểu thức lambda có đối sánh mẫu trên một đối số.
global Được sử dụng để tham chiếu không gian tên .NET cấp cao nhất.
if Được sử dụng trong các cấu trúc phân nhánh có điều kiện.
in Được sử dụng cho các biểu thức trình tự và, trong cú pháp dài dòng, để tách các biểu thức khỏi các ràng buộc.
inherit Được sử dụng để chỉ định một lớp cơ sở hoặc giao diện cơ sở.
inline Được sử dụng để chỉ ra một chức năng cần được tích hợp trực tiếp vào mã của người gọi.
interface Dùng để khai báo và triển khai các giao diện.
internal Được sử dụng để chỉ định rằng một thành viên có thể nhìn thấy bên trong một assembly nhưng không hiển thị bên ngoài nó.
lazy Được sử dụng để chỉ định một phép tính chỉ được thực hiện khi cần kết quả.
let Được sử dụng để liên kết hoặc ràng buộc tên với một giá trị hoặc hàm.
let! Được sử dụng trong quy trình làm việc không đồng bộ để liên kết tên với kết quả của một phép tính không đồng bộ hoặc, trong các biểu thức tính toán khác, được sử dụng để liên kết tên với một kết quả, thuộc kiểu tính toán.
match Được sử dụng để phân nhánh bằng cách so sánh một giá trị với một mẫu.
member Được sử dụng để khai báo một thuộc tính hoặc phương thức trong một kiểu đối tượng.
module Được sử dụng để liên kết tên với một nhóm các kiểu, giá trị và chức năng có liên quan, để tách nó khỏi mã khác một cách hợp lý.
mutable Dùng để khai báo một biến, tức là một giá trị có thể thay đổi được.
namespace Được sử dụng để liên kết tên với một nhóm các loại và mô-đun có liên quan, để tách nó khỏi mã khác một cách hợp lý.
new

Được sử dụng để khai báo, định nghĩa hoặc gọi một hàm tạo có thể tạo hoặc có thể tạo một đối tượng.

Cũng được sử dụng trong các ràng buộc tham số chung để chỉ ra rằng một kiểu phải có một hàm tạo nhất định.

not Không thực sự là một từ khóa. Tuy nhiên, không phải kết hợp struct được sử dụng như một ràng buộc tham số chung.
null

Cho biết sự vắng mặt của một đối tượng.

Cũng được sử dụng trong các ràng buộc tham số chung.

of Được sử dụng trong các liên hiệp phân biệt đối xử để chỉ ra loại giá trị, và trong khai báo ủy quyền và ngoại lệ.
open Được sử dụng để cung cấp nội dung của không gian tên hoặc mô-đun mà không cần đủ điều kiện.
or

Được sử dụng với điều kiện Boolean như một Boolean hoặc toán tử. Tương đương với ||.

Cũng được sử dụng trong các ràng buộc thành viên.

override Được sử dụng để triển khai một phiên bản của phương thức trừu tượng hoặc ảo khác với phiên bản cơ sở.
private Hạn chế quyền truy cập của một thành viên vào mã trong cùng loại hoặc mô-đun.
public Cho phép truy cập vào một thành viên từ bên ngoài loại.
rec Được sử dụng để chỉ ra rằng một hàm là đệ quy.
return Được sử dụng để chỉ ra một giá trị cần cung cấp là kết quả của một biểu thức tính toán.
return! Được sử dụng để chỉ ra một biểu thức tính toán, khi được đánh giá, cung cấp kết quả của biểu thức tính toán chứa.
select Được sử dụng trong biểu thức truy vấn để chỉ định trường hoặc cột nào cần trích xuất. Lưu ý rằng đây là một từ khóa theo ngữ cảnh, có nghĩa là nó không thực sự là một từ dành riêng và nó chỉ hoạt động giống như một từ khóa trong ngữ cảnh thích hợp.
static Được sử dụng để chỉ ra một phương thức hoặc thuộc tính có thể được gọi mà không có một thể hiện của kiểu hoặc một thành viên giá trị được chia sẻ giữa tất cả các thể hiện của kiểu.
struct

Dùng để khai báo một kiểu cấu trúc.

Cũng được sử dụng trong các ràng buộc tham số chung.

Được sử dụng để tương thích OCaml trong định nghĩa mô-đun.

then

Được sử dụng trong biểu thức điều kiện.

Cũng được sử dụng để thực hiện các hiệu ứng phụ sau khi xây dựng đối tượng.

to Được sử dụng trong vòng lặp for để chỉ ra một phạm vi.
true Được sử dụng như một nghĩa đen Boolean.
try Được sử dụng để giới thiệu một khối mã có thể tạo ra một ngoại lệ. Được sử dụng cùng với hoặc cuối cùng.
type Được sử dụng để khai báo một lớp, bản ghi, cấu trúc, liên hiệp phân biệt, kiểu liệt kê, đơn vị đo lường hoặc viết tắt kiểu.
upcast Được sử dụng để chuyển đổi sang loại cao hơn trong chuỗi kế thừa.
use Được sử dụng thay vì let cho các giá trị yêu cầu Dispose được gọi đến tài nguyên miễn phí.
use! Được sử dụng thay vì let! trong quy trình làm việc không đồng bộ và các biểu thức tính toán khác cho các giá trị yêu cầu Dispose được gọi đến tài nguyên giải phóng.
val Được sử dụng trong một chữ ký để chỉ ra một giá trị hoặc trong một kiểu để khai báo một thành viên, trong những tình huống hạn chế.
void Cho biết kiểu void .NET. Được sử dụng khi tương tác với các ngôn ngữ .NET khác.
when Được sử dụng cho các điều kiện Boolean (khi bảo vệ) trên mẫu khớp và để giới thiệu một mệnh đề ràng buộc cho một tham số kiểu chung.
while Giới thiệu một cấu trúc lặp.
with Được sử dụng cùng với từ khóa đối sánh trong biểu thức đối sánh mẫu. Cũng được sử dụng trong các biểu thức đối tượng, biểu thức sao chép bản ghi và phần mở rộng kiểu để giới thiệu các định nghĩa thành viên và giới thiệu các trình xử lý ngoại lệ.
yield Được sử dụng trong biểu thức trình tự để tạo ra giá trị cho một chuỗi.
yield! Được sử dụng trong một biểu thức tính toán để nối kết quả của một biểu thức tính toán đã cho vào một tập hợp các kết quả cho biểu thức tính toán có chứa.

Một số từ khóa dành riêng đến từ ngôn ngữ OCaml -

asr đất đai lor lsl lsr lxor mod dấu hiệu

Một số từ khóa dành riêng khác được giữ lại để mở rộng F # trong tương lai.

nguyên tử phá vỡ đã kiểm tra thành phần hăng sô hạn chế constructor
continue eager event external fixed functor include
method mixin object parallel process protected pure
sealed tailcall trait virtual volatile

Comments in F#

F# provides two types of comments −

  • One line comment starts with // symbol.
  • Multi line comment starts with (* and ends with *).

A Basic Program and Application Entry Point in F#

Generally, you don’t have any explicit entry point for F# programs. When you compile an F# application, the last file provided to the compiler becomes the entry point and all top level statements in that file are executed from top to bottom.

A well-written program should have a single top-level statement that would call the main loop of the program.

A very minimalistic F# program that would display ‘Hello World’ on the screen −

(* This is a comment *)
(* Sample Hello World program using F# *)
printfn "Hello World!"

When you compile and execute the program, it yields the following output −

Hello World!

The data types in F# can be classified as follows −

  • Integral types
  • Floating point types
  • Text types
  • Other types

Integral Data Type

The following table provides the integral data types of F#. These are basically integer data types.

F# Type Size Range Example Remarks
sbyte 1 byte -128 to 127

42y

-11y

8-bit signed integer
byte 1 byte 0 to 255

42uy

200uy

8-bit unsigned integer
int16 2 bytes -32768 to 32767

42s

-11s

16-bit signed integer
uint16 2 bytes 0 to 65,535

42us

200us

16-bit unsigned integer
int/int32 4 bytes -2,147,483,648 to 2,147,483,647

42

-11

32-bit signed integer
uint32 4 bytes 0 to 4,294,967,295

42u

200u

32-bit unsigned integer
int64 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

42L

-11L

64-bit signed integer
uint64 8 bytes 0 to 18,446,744,073,709,551,615

42UL

200UL

64-bit unsigned integer
bigint At least 4 bytes any integer

42I

1499999

9999999

9999999

9999999

9999I

arbitrary precision integer

Example

(* single byte integer *)
let x = 268.97f
let y = 312.58f
let z = x + y

printfn "x: %f" x
printfn "y: %f" y
printfn "z: %f" z

(* unsigned 8-bit natural number *)

let p = 2uy
let q = 4uy
let r = p + q

printfn "p: %i" p
printfn "q: %i" q
printfn "r: %i" r

(* signed 16-bit integer *)

let a = 12s
let b = 24s
let c = a + b

printfn "a: %i" a
printfn "b: %i" b
printfn "c: %i" c

(* signed 32-bit integer *)

let d = 212l
let e = 504l
let f = d + e

printfn "d: %i" d
printfn "e: %i" e
printfn "f: %i" f

When you compile and execute the program, it yields the following output −

x: 1
y: 2
z: 3
p: 2
q: 4
r: 6
a: 12
b: 24
c: 36
d: 212
e: 504
f: 716

Floating Point Data Types

The following table provides the floating point data types of F#.

F# Type Size Range Example Remarks
float32 4 bytes ±1.5e-45 to ±3.4e38

42.0F

-11.0F

32-bit signed floating point number (7 significant digits)
float 8 bytes ±5.0e-324 to ±1.7e308

42.0

-11.0

64-bit signed floating point number (15-16 significant digits)
decimal 16 bytes ±1.0e-28 to ±7.9e28

42.0M

-11.0M

128-bit signed floating point number (28-29 significant digits)
BigRational At least 4 bytes Any rational number.

42N

-11N

Arbitrary precision rational number. Using this type requires a reference to FSharp.PowerPack.dll.

Example

(* 32-bit signed floating point number *)
(* 7 significant digits *)

let d = 212.098f
let e = 504.768f
let f = d + e

printfn "d: %f" d
printfn "e: %f" e
printfn "f: %f" f

(* 64-bit signed floating point number *)
(* 15-16 significant digits *)
let x = 21290.098
let y = 50446.768
let z = x + y

printfn "x: %g" x
printfn "y: %g" y
printfn "z: %g" z

When you compile and execute the program, it yields the following output −

d: 212.098000
e: 504.768000
f: 716.866000
x: 21290.1
y: 50446.8
z: 71736.9

Text Data Types

The following table provides the text data types of F#.

F# Type Size Range Example Remarks
char 2 bytes U+0000 to U+ffff

'x'

'\t'

Single unicode characters
string 20 + (2 * string's length) bytes 0 to about 2 billion characters

"Hello"

"World"

Unicode text

Example

let choice = 'y'
let name = "Zara Ali"
let org = "Tutorials Point"

printfn "Choice: %c" choice
printfn "Name: %s" name
printfn "Organisation: %s" org

When you compile and execute the program, it yields the following output −

Choice: y
Name: Zara Ali
Organisation: Tutorials Point

Other Data Types

The following table provides some other data types of F#.

F# Type Size Range Example Remarks
bool 1 byte Only two possible values, true or false

true

false

Stores boolean values

Example

let trueVal = true
let falseVal = false

printfn "True Value: %b" (trueVal)
printfn "False Value: %b" (falseVal)

When you compile and execute the program, it yields the following output −

True Value: true
False Value: false

A variable is a name given to a storage area that our programs can manipulate. Each variable has a specific type, which determines the size and layout of the variable's memory; the range of values that can be stored within that memory; and the set of operations that can be applied to the variable.

Variable Declaration in F#

The let keyword is used for variable declaration −

For example,

let x = 10

It declares a variable x and assigns the value 10 to it.

You can also assign an expression to a variable −

let x = 10
let y = 20
let z = x + y

The following example illustrates the concept −

Example

let x = 10
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

When you compile and execute the program, it yields the following output −

x: 10
y: 20
z: 30

Variables in F# are immutable, which means once a variable is bound to a value, it can’t be changed. They are actually compiled as static read-only properties.

The following example demonstrates this.

Example

let x = 10
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

let x = 15
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

When you compile and execute the program, it shows the following error message −

Duplicate definition of value 'x'
Duplicate definition of value 'Y'
Duplicate definition of value 'Z'

Variable Definition With Type Declaration

A variable definition tells the compiler where and how much storage for the variable should be created. A variable definition may specify a data type and contains a list of one or more variables of that type as shown in the following example.

Example

let x:int32 = 10
let y:int32 = 20
let z:int32 = x + y

printfn "x: %d" x
printfn "y: %d" y
printfn "z: %d" z

let p:float = 15.99
let q:float = 20.78
let r:float = p + q

printfn "p: %g" p
printfn "q: %g" q
printfn "r: %g" r

When you compile and execute the program, it shows the following error message −

x: 10
y: 20
z: 30
p: 15.99
q: 20.78
r: 36.77

Mutable Variables

At times you need to change the values stored in a variable. To specify that there could be a change in the value of a declared and assigned variable, in later part of a program, F# provides the mutable keyword. You can declare and assign mutable variables using this keyword, whose values you will change.

The mutable keyword allows you to declare and assign values in a mutable variable.

You can assign some initial value to a mutable variable using the let keyword. However, to assign new subsequent value to it, you need to use the operator.

For example,

let mutable x = 10
x ← 15

The following example will clear the concept −

Example

let mutable x = 10
let y = 20
let mutable z = x + y

printfn "Original Values:"
printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

printfn "Let us change the value of x"
printfn "Value of z will change too."

x <- 15
z <- x + y

printfn "New Values:"
printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

When you compile and execute the program, it yields the following output −

Original Values:
x: 10
y: 20
z: 30
Let us change the value of x
Value of z will change too.
New Values:
x: 15
y: 20
z: 35

An operator is a symbol that tells the compiler to perform specific mathematical or logical manipulations. F# is rich in built-in operators and provides the following types of operators −

  • Arithmetic Operators
  • Comparison Operators
  • Boolean Operators
  • Bitwise Operators

Arithmetic Operators

The following table shows all the arithmetic operators supported by F# language. Assume variable A holds 10 and variable B holds 20 then −

Show Example

Operator Description Example
+ Adds two operands A + B will give 30
- Subtracts second operand from the first A - B will give -10
* Multiplies both operands A * B will give 200
/ Divides numerator by de-numerator B / A will give 2
% Modulus Operator and remainder of after an integer division B % A will give 0
** Exponentiation Operator, raises an operand to the power of another B**A will give 2010

Comparison Operators

The following table shows all the comparison operators supported by F# language. These binary comparison operators are available for integral and floating-point types. These operators return values of type bool.

Assume variable A holds 10 and variable B holds 20, then −

Show Example

Operator Description Example
= Checks if the values of two operands are equal or not, if yes then condition becomes true. (A == B) is not true.
<> Checks if the values of two operands are equal or not, if values are not equal then condition becomes true. (A <> B) is true.
> Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true. (A > B) is not true.
< Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true. (A < B) is true.
>= Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true. (A >= B) is not true.
<= Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true. (A <= B) is true.

Boolean Operators

The following table shows all the Boolean operators supported by F# language. Assume variable A holds true and variable B holds false, then −

Show Example

Operator Description Example
&& Called Boolean AND operator. If both the operands are non-zero, then condition becomes true. (A && B) is false.
|| Called Boolean OR Operator. If any of the two operands is non-zero, then condition becomes true. (A || B) is true.
not Called Boolean NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false. not (A && B) is true.

Bitwise Operators

Bitwise operators work on bits and perform bit-by-bit operation. The truth tables for &&& (bitwise AND), ||| (bitwise OR), and ^^^ (bitwise exclusive OR) are as follows −

Show Example

p q p &&& q p ||| q p ^^^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

Assume if A = 60; and B = 13; now in binary format they will be as follows −

A = 0011 1100

B = 0000 1101

A&&&B = 0000 1100

A|||B = 0011 1101

A^^^B = 0011 0001

~~~A = 1100 0011

The Bitwise operators supported by F# language are listed in the following table. Assume variable A holds 60 and variable B holds 13, then −

Operator Description Example
&&& Binary AND Operator copies a bit to the result if it exists in both operands. (A &&& B) will give 12, which is 0000 1100
||| Binary OR Operator copies a bit if it exists in either operand. (A ||| B) will give 61, which is 0011 1101
^^^ Binary XOR Operator copies the bit if it is set in one operand but not both. (A ^^^ B) will give 49, which is 0011 0001
~~~ Binary Ones Complement Operator is unary and has the effect of 'flipping' bits. (~~~A) will give -61, which is 1100 0011 in 2's complement form.
<<< Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand. A <<< 2 will give 240 which is 1111 0000
>>> Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand. A >>> 2 will give 15 which is 0000 1111

Operators Precedence

The following table shows the order of precedence of operators and other expression keywords in the F# language, from lowest precedence to the highest precedence.

Show Example

Operator Associativity
as Right
when Right
| (pipe) Left
; Right
let Non associative
function, fun, match, try Non associative
if Non associative
Right
:= Right
, Non associative
or, || Left
&, && Left
< op, >op, =, |op, &op Left
&&& , |||, ^^^, ~~~, <<<, >>> Left
^ op Right
:: Right
:?>, :? Non associative
- op, +op, (binary) Left
* op, /op, %op Left
** op Right
f x (function application) Left
| (pattern match) Right
prefix operators (+op, -op, %, %%, &, &&, !op, ~op) Left
. Left
f(x) Left
f<types> Left

Decision making structures require that the programmer specify one or more conditions to be evaluated or tested by the program. It should be along with a statement or statements to be executed if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false.

Following is the general form of a typical decision making structure found in most of the programming languages −

F# programming language provides the following types of decision making statements.

Statement Description
if /then statement An if/then statement consists of a Boolean expression followed by one or more statements.
if/then/ else statement An if/then statement can be followed by an optional else statement, which executes when the Boolean expression is false.
if/then/elif/else statement An if/then/elif/else statement allows you to have multiple else branches.
nested if statements You can use one if or else if statement inside another if or else if statement(s).

Programming languages provide various control structures that allow for more complicated execution paths.

A loop statement allows us to execute a statement or group of statements multiple times and following is the general form of a loop statement in most of the programming languages −

F# provides the following types of loops to handle the looping requirements.

Loop Type Description
for… to and for… downto expressions The for...to expression is used to iterate in a loop over a range of values of a loop variable. The for… downto expression reduces the value of loop variable.
for … in expression This form of for loop is used to iterate over collections of items i.e., loops over collections and sequences
While…do loop Repeats a statement or group of statements while a given condition is true. It tests the condition before executing the loop body.
nested loops You can use one or more loop inside any other for or while loop.

In F#, functions work like data types. You can declare and use a function in the same way like any other variable.

Since functions can be used like any other variables, you can −

  • Create a function, with a name and associate that name with a type.
  • Assign it a value.
  • Perform some calculation on that value.
  • Pass it as a parameter to another function or sub-routine.
  • Return a function as the result of another function.

Defining a Function

Functions are defined by using the let keyword. A function definition has the following syntax −

let [inline] function-name parameter-list [ : return-type ]
= function-body

Where,

  • function-name is an identifier that represents the function.

  • parameter-list gives the list of parameters separated by spaces. You can also specify an explicit type for each parameter and if not specified compiler tends to deduce it from the function body (like variables).

  • function-body consists of an expression, or a compound expression consisting of a number of expressions. The final expression in the function body is the return value.

  • return-type is a colon followed by a type and is optional. If the return type is not specified, then the compiler determines it from the final expression in the function body.

Parameters of a Function

You list the names of parameters right after the function name. You can specify the type of a parameter. The type of the parameter should follow the name of the parameter separated by a colon.

If no parameter type is specified, it is inferred by the compiler.

For example −

let doubleIt (x : int) = 2 * x

Calling a Function

A function is called by specifying the function name followed by a space and then any arguments separated by spaces.

For example −

let vol = cylinderVolume 3.0 5.0

The following programs illustrate the concepts.

Example 1

The following program calculates the volume of a cylinder when the radius and length are given as parameters

// the function calculates the volume of
// a cylinder with radius and length as parameters

let cylinderVolume radius length : float =

   // function body
   let pi = 3.14159
   length * pi * radius * radius

let vol = cylinderVolume 3.0 5.0
printfn " Volume: %g " vol

When you compile and execute the program, it yields the following output −

Volume: 141.372

Example 2

The following program returns the larger value of two given parameters −

// the function returns the larger value between two
// arguments

let max num1 num2 : int32 =
   // function body
   if(num1>num2)then
      num1
   else
      num2

let res = max 39 52
printfn " Max Value: %d " res

When you compile and execute the program, it yields the following output −

Max Value: 52

Example 3

let doubleIt (x : int) = 2 * x
printfn "Double 19: %d" ( doubleIt(19))

When you compile and execute the program, it yields the following output −

Double 19: 38

Recursive Functions

Recursive functions are functions that call themselves.

You define a recursive using the let rec keyword combination.

Syntax for defining a recursive function is −

//Recursive function definition
let rec function-name parameter-list = recursive-function-body

For example −

let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)

Example 1

The following program returns Fibonacci 1 to 10 −

let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
for i = 1 to 10 do
   printfn "Fibonacci %d: %d" i (fib i)

When you compile and execute the program, it yields the following output −

Fibonacci 1: 1
Fibonacci 2: 2
Fibonacci 3: 3
Fibonacci 4: 5
Fibonacci 5: 8
Fibonacci 6: 13
Fibonacci 7: 21
Fibonacci 8: 34
Fibonacci 9: 55
Fibonacci 10: 89

Example 2

The following program returns factorial 8 −

open System
let rec fact x =
   if x < 1 then 1
   else x * fact (x - 1)
Console.WriteLine(fact 8)

When you compile and execute the program, it yields the following output −

40320

Arrow Notations in F#

F# reports about data type in functions and values, using a chained arrow notation. Let us take an example of a function that takes one int input, and returns a string. In arrow notation, it is written as −

int -> string

Data types are read from left to right.

Let us take another hypothetical function that takes two int data inputs and returns a string.

let mydivfunction x y = (x / y).ToString();;

F# reports the data type using chained arrow notation as −

val mydivfunction : x:int -> y:int -> string

The return type is represented by the rightmost data type in chained arrow notation.

Some more examples −

Notation Meaning
float → float → float The function takes two float inputs, returns another float.
int → string → float The function takes an int and a string input, returns a float.

Lambda Expressions

A lambda expression is an unnamed function.

Let us take an example of two functions −

let applyFunction ( f: int -> int -> int) x y = f x y
let mul x y = x * y
let res = applyFunction mul 5 7
printfn "%d" res

When you compile and execute the program, it yields the following output −

35

Now in the above example, if instead of defining the function mul, we could have used lambda expressions as −

let applyFunction ( f: int -> int -> int) x y = f x y
let res = applyFunction (fun x y -> x * y ) 5 7
printfn "%d" res

When you compile and execute the program, it yields the following output −

35

Function Composition and Pipelining

In F#, one function can be composed from other functions.

The following example shows the composition of a function named f, from two functions function1 and function2 −

let function1 x = x + 1
let function2 x = x * 5

let f = function1 >> function2
let res = f 10
printfn "%d" res

When you compile and execute the program, it yields the following output −

55

F# also provides a feature called pipelining of functions. Pipelining allows function calls to be chained together as successive operations.

The following example shows that −

let function1 x = x + 1
let function2 x = x * 5

let res = 10 |> function1 |> function2
printfn "%d" res

When you compile and execute the program, it yields the following output −

55

In F#, the string type represents immutable text as a sequence of Unicode characters.

String Literals

String literals are delimited by the quotation mark (") character.

Some special characters are there for special uses like newline, tab, etc. They are encoded using backslash (\) character. The backslash character and the related character make the escape sequence. The following table shows the escape sequence supported by F#.

Character Escape sequence
Backspace \b
Newline \n
Carriage return \r
Tab \t
Backslash \\
Quotation mark \"
Apostrophe \'
Unicode character \uXXXX or \UXXXXXXXX (where X indicates a hexadecimal digit)

Ways of lgnoring the Escape Sequence

The following two ways makes the compiler ignore the escape sequence −

  • Using the @ symbol.
  • Enclosing the string in triple quotes.

When a string literal is preceded by the @ symbol, it is called a verbatim string. In that way, all escape sequences in the string are ignored, except that two quotation mark characters are interpreted as one quotation mark character.

When a string is enclosed by triple quotes, then also all escape sequences are ignored, including double quotation mark characters.

Example

The following example demonstrates this technique showing how to work with XML or other structures that include embedded quotation marks −

// Using a verbatim string
let xmldata = @"<book author=""Lewis, C.S"" title=""Narnia"">"
printfn "%s" xmldata

When you compile and execute the program, it yields the following output −

<book author="Lewis, C.S" title="Narnia">

Basic Operators on Strings

The following table shows the basic operations on strings −

Value Description
collect : (char → string) → string → string Creates a new string whose characters are the results of applying a specified function to each of the characters of the input string and concatenating the resulting strings.
concat : string → seq<string> → string Returns a new string made by concatenating the given strings with a separator.
exists : (char → bool) → string → bool Tests if any character of the string satisfies the given predicate.
forall : (char → bool) → string → bool Tests if all characters in the string satisfy the given predicate.
init : int → (int → string) → string Creates a new string whose characters are the results of applying a specified function to each index and concatenating the resulting strings.
iter : (char → unit) → string → unit Applies a specified function to each character in the string.
iteri : (int → char → unit) → string → unit Applies a specified function to the index of each character in the string and the character itself.
length : string → int Returns the length of the string.
map : (char → char) → string → string Creates a new string whose characters are the results of applying a specified function to each of the characters of the input string.
mapi : (int → char → char) → string → string Creates a new string whose characters are the results of applying a specified function to each character and index of the input string.
replicate : int → string → string Returns a string by concatenating a specified number of instances of a string.

The following examples demonstrate the uses of some of the above functionalities −

Example 1

The String.collect function builds a new string whose characters are the results of applying a specified function to each of the characters of the input string and concatenating the resulting strings.

let collectTesting inputS =
   String.collect (fun c -> sprintf "%c " c) inputS
printfn "%s" (collectTesting "Happy New Year!")

When you compile and execute the program, it yields the following output −

H a p p y N e w Y e a r !

Example 2

The String.concat function concatenates a given sequence of strings with a separator and returns a new string.

let strings = [ "Tutorials Point"; "Coding Ground"; "Absolute Classes" ]
let ourProducts = String.concat "\n" strings
printfn "%s" ourProducts

When you compile and execute the program, it yields the following output −

Tutorials Point
Coding Ground
Absolute Classes

Example 3

The String.replicate method returns a string by concatenating a specified number of instances of a string.

printfn "%s" <| String.replicate 10 "*! "

When you compile and execute the program, it yields the following output −

*! *! *! *! *! *! *! *! *! *!

The option type in F# is used in calculations when there may or may not exist a value for a variable or function. Option types are used for representing optional values in calculations. They can have two possible values − Some(x) or None.

For example, a function performing a division will return a value in normal situation, but will throw exceptions in case of a zero denominator. Using options here will help to indicate whether the function has succeeded or failed.

An option has an underlying type and can hold a value of that type, or it might not have a value.

Using Options

Let us take the example of division function. The following program explains this −

Let us write a function div, and send two arguments to it 20 and 5 −

let div x y = x / y
let res = div 20 5
printfn "Result: %d" res

When you compile and execute the program, it yields the following output −

Result: 4

If the second argument is zero, then the program throws an exception −

let div x y = x / y
let res = div 20 0
printfn "Result: %d" res

When you compile and execute the program, it yields the following output −

Unhandled Exception:
System.DivideByZeroException: Division by zero

In such cases, we can use option types to return Some (value) when the operation is successful or None if the operation fails.

The following example demonstrates the use of options −

Example

let div x y =
   match y with
   | 0 -> None
   | _ -> Some(x/y)

let res : int option = div 20 4
printfn "Result: %A " res

When you compile and execute the program, it yields the following output −

Result: Some 5

Option Properties and Methods

The option type supports the following properties and methods −

Property or method Type Description
None 'T option A static property that enables you to create an option value that has the None value.
IsNone bool Returns true if the option has the None value.
IsSome bool Returns true if the option has a value that is not None.
Some 'T option A static member that creates an option that has a value that is not None.
Value 'T Returns the underlying value, or throws a NullReferenceException if the value is None.

Example 1

let checkPositive (a : int) =
   if a > 0 then
      Some(a)
   else
      None

let res : int option = checkPositive(-31)
printfn "Result: %A " res

When you compile and execute the program, it yields the following output −

Result: <null>

Example 2

let div x y =
   match y with
   | 0 -> None
   | _ -> Some(x/y)

let res : int option = div 20 4
printfn "Result: %A " res
printfn "Result: %A " res.Value

When you compile and execute the program, it yields the following output −

Result: Some 5
Result: 5

Example 3

let isHundred = function
   | Some(100) -> true
   | Some(_) | None -> false

printfn "%A" (isHundred (Some(45)))
printfn "%A" (isHundred (Some(100)))
printfn "%A" (isHundred None)

When you compile and execute the program, it yields the following output −

false
true
false

A tuplelà một tập hợp các giá trị được phân tách bằng dấu phẩy. Chúng được sử dụng để tạo cấu trúc dữ liệu đặc biệt, nhóm các giá trị có liên quan với nhau.

Ví dụ, (“Zara Ali”, “Hyderabad”, 10) là một bộ 3 với hai giá trị chuỗi và một giá trị int, nó có kiểu (string * string * int).

Tuples có thể là cặp, bộ ba, v.v., cùng loại hoặc khác loại.

Một số ví dụ được cung cấp ở đây -

// Tuple of two integers.
( 4, 5 )

// Triple of strings.
( "one", "two", "three" )

// Tuple of unknown types.
( a, b )

// Tuple that has mixed types.
( "Absolute Classes", 1, 2.0 )

// Tuple of integer expressions.
( a * 4, b + 7)

Thí dụ

Chương trình này có một hàm nhận một bộ bốn giá trị float và trả về giá trị trung bình:

let averageFour (a, b, c, d) =
   let sum = a + b + c + d
   sum / 4.0

let avg:float = averageFour (4.0, 5.1, 8.0, 12.0)
printfn "Avg of four numbers: %f" avg

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Avg of four numbers: 7.275000

Tiếp cận các thành viên Tuple Cá nhân

Các thành viên riêng lẻ của một bộ tuple có thể được đánh giá và in bằng cách sử dụng khớp mẫu.

Ví dụ sau minh họa khái niệm -

Thí dụ

let display tuple1 =
   match tuple1 with
   | (a, b, c) -> printfn "Detail Info: %A %A %A" a b c

display ("Zara Ali", "Hyderabad", 10 )

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Detail Info: "Zara Ali" "Hyderabad" 10

F # có hai hàm tích hợp, fstsnd, trả về mục đầu tiên và mục thứ hai trong một bộ 2.

Ví dụ sau minh họa khái niệm -

Thí dụ

printfn "First member: %A" (fst(23, 30))
printfn "Second member: %A" (snd(23, 30))

printfn "First member: %A" (fst("Hello", "World!"))
printfn "Second member: %A" (snd("Hello", "World!"))

let nameTuple = ("Zara", "Ali")

printfn "First Name: %A" (fst nameTuple)
printfn "Second Name: %A" (snd nameTuple)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

First member: 23
Second member: 30
First member: "Hello"
Second member: "World!"
First Name: "Zara"
Second Name: "Ali"

A recordtương tự như một tuple, tuy nhiên nó chứa các trường được đặt tên. Ví dụ,

type website =
   { title : string;
      url : string }

Xác định bản ghi

Bản ghi được định nghĩa là một loại bằng cách sử dụng type từ khóa và các trường của bản ghi được xác định dưới dạng danh sách được phân tách bằng dấu chấm phẩy.

Cú pháp để xác định một bản ghi là:

type recordName =
   { [ fieldName : dataType ] + }

Tạo bản ghi

Bạn có thể tạo bản ghi bằng cách chỉ định các trường của bản ghi. Ví dụ: hãy để chúng tôi tạo một bản ghi trang web có tên là trang chủ -

let homepage = { Title = "TutorialsPoint"; Url = "www.tutorialspoint.com" }

Các ví dụ sau đây sẽ giải thích các khái niệm -

ví dụ 1

Chương trình này định nghĩa một loại bản ghi có tên là trang web. Sau đó, nó tạo ra một số bản ghi của loại trang web và in các bản ghi.

(* defining a record type named website *)
type website =
   { Title : string;
      Url : string }

(* creating some records *)
let homepage = { Title = "TutorialsPoint"; Url = "www.tutorialspoint.com" }
let cpage = { Title = "Learn C"; Url = "www.tutorialspoint.com/cprogramming/index.htm" }
let fsharppage = { Title = "Learn F#"; Url = "www.tutorialspoint.com/fsharp/index.htm" }
let csharppage = { Title = "Learn C#"; Url = "www.tutorialspoint.com/csharp/index.htm" }

(*printing records *)
(printfn "Home Page: Title: %A \n \t URL: %A") homepage.Title homepage.Url
(printfn "C Page: Title: %A \n \t URL: %A") cpage.Title cpage.Url
(printfn "F# Page: Title: %A \n \t URL: %A") fsharppage.Title fsharppage.Url
(printfn "C# Page: Title: %A \n \t URL: %A") csharppage.Title csharppage.Url

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Home Page: Title: "TutorialsPoint"
       URL: "www.tutorialspoint.com"
C Page: Title: "Learn C"
      URL: "www.tutorialspoint.com/cprogramming/index.htm"
F# Page: Title: "Learn F#"
      URL: "www.tutorialspoint.com/fsharp/index.htm"
C# Page: Title: "Learn C#"
      URL: "www.tutorialspoint.com/csharp/index.htm"

Ví dụ 2

type student =
   { Name : string;
      ID : int;
      RegistrationText : string;
      IsRegistered : bool }

let getStudent name id =
   { Name = name; ID = id; RegistrationText = null; IsRegistered = false }

let registerStudent st =
   { st with
      RegistrationText = "Registered";
      IsRegistered = true }

let printStudent msg st =
   printfn "%s: %A" msg st

let main() =
   let preRegisteredStudent = getStudent "Zara" 10
   let postRegisteredStudent = registerStudent preRegisteredStudent

   printStudent "Before Registration: " preRegisteredStudent
   printStudent "After Registration: " postRegisteredStudent

main()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Before Registration: : {Name = "Zara";
   ID = 10;
   RegistrationText = null;
   IsRegistered = false;}
After Registration: : {Name = "Zara";
   ID = 10;
   RegistrationText = "Registered";
   IsRegistered = true;}

Trong F #, một danh sách là một chuỗi các phần tử cùng kiểu có thứ tự, bất biến. Ở một mức độ nào đó, nó tương đương với cấu trúc dữ liệu danh sách liên kết.

Mô-đun F #, Microsoft.FSharp.Collections.List,có các hoạt động phổ biến trên danh sách. Tuy nhiên, F # nhập mô-đun này tự động và làm cho nó có thể truy cập vào mọi ứng dụng F #.

Tạo và khởi tạo danh sách

Sau đây là các cách tạo danh sách khác nhau -

  • Sử dụng danh sách literals.

  • Sử dụng cons (::) nhà điều hành.

  • Sử dụng List.init phương thức của mô-đun Danh sách.

  • Sử dụng một số syntactic constructs gọi là List Comprehensions.

Liệt kê các chữ

Trong phương pháp này, bạn chỉ cần chỉ định một chuỗi giá trị được phân tách bằng dấu chấm phẩy trong dấu ngoặc vuông. Ví dụ -

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

Khuyết điểm (: :) Toán tử

Với phương pháp này, bạn có thể thêm một số giá trị bằng cách thêm trước hoặc cons-ingnó vào danh sách hiện có bằng toán tử ::. Ví dụ -

let list2 = 1::2::3::4::5::6::7::8::9::10::[];;

[] biểu thị một danh sách trống.

Liệt kê phương pháp init

Phương thức List.init của mô-đun Danh sách thường được sử dụng để tạo danh sách. Phương thức này có kiểu -

val init : int -> (int -> 'T) -> 'T list

Đối số đầu tiên là độ dài mong muốn của danh sách mới và đối số thứ hai là một hàm khởi tạo, hàm này tạo các mục trong danh sách.

Ví dụ,

let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))

Tại đây, hàm chỉ mục tạo danh sách.

Liệt kê toàn bộ

Danh sách hiểu là cấu trúc cú pháp đặc biệt được sử dụng để tạo danh sách.

Cú pháp hiểu danh sách F # có hai dạng - phạm vi và trình tạo.

Dải ô có các cấu trúc - [bắt đầu .. kết thúc] và [bắt đầu .. bước .. kết thúc]

Ví dụ,

let list3 = [1 .. 10]

Trình tạo có cấu trúc - [đối với x trong bộ sưu tập do ... sản lượng expr]

Ví dụ,

let list6 = [ for a in 1 .. 10 do yield (a * a) ]

Như yield từ khóa đẩy một giá trị vào danh sách, từ khóa, yield!, đẩy một tập hợp các giá trị vào danh sách.

Hàm sau thể hiện các phương pháp trên:

Thí dụ

(* using list literals *)
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1

(*using cons operator *)
let list2 = 1 :: 2 :: 3 :: []
printfn "The list: %A" list2

(* using range constructs*)
let list3 = [1 .. 10]
printfn "The list: %A" list3

(* using range constructs *)
let list4 = ['a' .. 'm']
printfn "The list: %A" list4

(* using init method *)
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
printfn "The list: %A" list5

(* using yield operator *)
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
printfn "The list: %A" list6

(* using yield operator *)
let list7 = [ for a in 1 .. 100 do if a % 3 = 0 && a % 5 = 0 then yield a]
printfn "The list: %A" list7

(* using yield! operator *)
let list8 = [for a in 1 .. 3 do yield! [ a .. a + 3 ] ]
printfn "The list: %A" list8

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: [1; 2; 3]
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: ['a'; 'b'; 'c'; 'd'; 'e'; 'f'; 'g'; 'h'; 'i'; 'j'; 'k'; 'l'; 'm']
The list: [(0, 0, 0); (1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64)]
The list: [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
The list: [15; 30; 45; 60; 75; 90]
The list: [1; 2; 3; 4; 2; 3; 4; 5; 3; 4; 5; 6]

Thuộc tính của kiểu dữ liệu danh sách

Bảng sau đây cho thấy các thuộc tính khác nhau của kiểu dữ liệu danh sách:

Bất động sản Kiểu Sự miêu tả
Cái đầu 'T Yếu tố đầu tiên.
Trống 'T danh sách Thuộc tính tĩnh trả về danh sách trống có kiểu thích hợp.
IsEmpty bool true nếu danh sách không có phần tử.
Mục 'T Phần tử tại chỉ mục được chỉ định (dựa trên không).
Chiều dài int Số lượng phần tử.
Đuôi 'T danh sách Danh sách không có phần tử đầu tiên.

Ví dụ sau cho thấy việc sử dụng các thuộc tính này:

Thí dụ

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]

// Use of Properties
printfn "list1.IsEmpty is %b" (list1.IsEmpty)
printfn "list1.Length is %d" (list1.Length)
printfn "list1.Head is %d" (list1.Head)
printfn "list1.Tail.Head is %d" (list1.Tail.Head)
printfn "list1.Tail.Tail.Head is %d" (list1.Tail.Tail.Head)
printfn "list1.Item(1) is %d" (list1.Item(1))

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

list1.IsEmpty is false
list1.Length is 8
list1.Head is 2
list1.Tail.Head is 4
list1.Tail.Tail.Head is 6
list1.Item(1) is 4

Các toán tử cơ bản trong danh sách

Bảng sau đây trình bày các thao tác cơ bản trên kiểu dữ liệu danh sách:

Giá trị Sự miêu tả
nối thêm: 'Danh sách T →' Danh sách T → 'Danh sách T Trả về một danh sách mới chứa các phần tử của danh sách đầu tiên theo sau là các phần tử của danh sách thứ hai.
trung bình: 'T danh sách → ^ T Trả về giá trị trung bình của các phần tử trong danh sách.
AverageBy: ('T → ^ U) →' Danh sách T → ^ U Trả về giá trị trung bình của các phần tử được tạo bằng cách áp dụng hàm cho từng phần tử của danh sách.
chọn: ('T →' U option) → 'T list →' U list Áp dụng chức năng đã cho cho từng phần tử của danh sách. Trả về danh sách bao gồm các kết quả cho từng phần tử mà hàm trả vềSome.
thu thập: ('T →' Danh sách U) → 'Danh sách T →' Danh sách U Đối với mỗi phần tử của danh sách, hãy áp dụng chức năng đã cho. Nối tất cả các kết quả và trả về danh sách kết hợp.
concat: seq <'T list> →' T list Trả về một danh sách mới chứa các phần tử của từng danh sách theo thứ tự.
rỗng: 'T danh sách Trả về một danh sách trống của kiểu đã cho.
tồn tại: ('T → bool) →' Danh sách T → bool Kiểm tra xem có phần tử nào của danh sách thỏa mãn vị từ đã cho hay không.
tồn tại2: ('T1 →' T2 → bool) → 'Danh sách T1 →' Danh sách T2 → bool Kiểm tra xem có cặp phần tử tương ứng nào của danh sách thỏa mãn vị từ đã cho hay không.
bộ lọc: ('T → bool) →' Danh sách T → 'Danh sách T Trả về một tập hợp mới chỉ chứa các phần tử của tập hợp mà vị từ đã cho trả về true.
find: ('T → bool) →' T list → 'T Trả về phần tử đầu tiên mà hàm đã cho trả về true.
findIndex: ('T → bool) →' T list → int Trả về chỉ số của phần tử đầu tiên trong danh sách thỏa mãn vị từ đã cho.
gấp: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → 'Danh sách T →' Trạng thái Áp dụng một hàm cho từng phần tử của tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Hàm này nhận đối số thứ hai và áp dụng hàm cho nó và phần tử đầu tiên của danh sách. Sau đó, nó chuyển kết quả này vào hàm cùng với phần tử thứ hai, v.v. Cuối cùng, nó trả về kết quả cuối cùng. Nếu hàm đầu vào là f và các phần tử là i0 ... iN, thì hàm này tính f (... (fs i0) i1 ...) iN.
fold2: ('Trạng thái →' T1 → 'T2 →' Trạng thái) → 'Trạng thái →' Danh sách T1 → 'Danh sách T2 →' Trạng thái Áp dụng một hàm cho các phần tử tương ứng của hai tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Các bộ sưu tập phải có kích thước giống hệt nhau. Nếu hàm đầu vào là f và các phần tử là i0 ... iN và j0 ... jN, thì hàm này tính f (... (fs i0 j0) ...) iN jN.
foldBack: ('T →' Trạng thái → 'Trạng thái) →' Danh sách T → 'Trạng thái →' Trạng thái Áp dụng một hàm cho từng phần tử của tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Nếu hàm đầu vào làf và các phần tử là i0 ... iN thì tính f i0 (... (f iN s)).
foldBack2: ('T1 →' T2 → 'Trạng thái →' Trạng thái) → 'Danh sách T1 →' Danh sách T2 → 'Trạng thái →' Trạng thái Áp dụng một hàm cho các phần tử tương ứng của hai tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Các bộ sưu tập phải có kích thước giống hệt nhau. Nếu hàm đầu vào là f và các phần tử là i0 ... iN và j0 ... jN, thì hàm này tính f i0 j0 (... (f iN jN s)).
forall: ('T → bool) →' T list → bool Kiểm tra xem tất cả các phần tử của tập hợp có thỏa mãn vị từ đã cho hay không.
forall2: ('T1 →' T2 → bool) → 'Danh sách T1 →' Danh sách T2 → bool Kiểm tra xem tất cả các phần tử tương ứng của tập hợp có thỏa mãn từng cặp vị từ đã cho hay không.
head: 'T list →' T Trả về phần tử đầu tiên của danh sách.
init: int → (int → 'T) →' T danh sách Tạo danh sách bằng cách gọi trình tạo đã cho trên mỗi chỉ mục.
isEmpty: 'T list → bool Lợi nhuận true nếu danh sách không chứa phần tử, false nếu không thì.
iter: ('T → đơn vị) →' T danh sách → đơn vị Áp dụng chức năng đã cho cho từng phần tử của tập hợp.
iter2: ('T1 →' T2 → đơn vị) → 'Danh sách T1 →' Danh sách T2 → đơn vị Áp dụng chức năng đã cho cho hai tập hợp đồng thời. Các bộ sưu tập phải có kích thước giống hệt nhau.
iteri: (int → 'T → đơn vị) →' Danh sách T → đơn vị Áp dụng chức năng đã cho cho từng phần tử của tập hợp. Số nguyên được truyền vào hàm cho biết chỉ số của phần tử.
iteri2: (int → 'T1 →' T2 → đơn vị) → 'Danh sách T1 →' Danh sách T2 → đơn vị Áp dụng chức năng đã cho cho hai tập hợp đồng thời. Các bộ sưu tập phải có kích thước giống hệt nhau. Số nguyên được truyền vào hàm cho biết chỉ số của phần tử.
length: 'T list → int Trả về độ dài của danh sách.
map: ('T →' U) → 'Danh sách T →' Danh sách U Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho từng phần tử của tập hợp.
map2: ('T1 →' T2 → 'U) →' Danh sách T1 → 'Danh sách T2 →' Danh sách U Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho các phần tử tương ứng của hai tập hợp theo cặp.
map3: ('T1 →' T2 → 'T3 →' U) → 'Danh sách T1 →' Danh sách T2 → 'Danh sách T3 →' Danh sách U Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho các phần tử tương ứng của ba tập hợp đồng thời.
mapi: (int → 'T →' U) → 'T list →' U list Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho từng phần tử của tập hợp. Chỉ số số nguyên được chuyển đến hàm cho biết chỉ số (từ 0) của phần tử được chuyển đổi.
mapi2: (int → 'T1 →' T2 → 'U) →' Danh sách T1 → 'Danh sách T2 →' Danh sách U Giống như List.mapi, nhưng ánh xạ các phần tử tương ứng từ hai danh sách có độ dài bằng nhau.
tối đa: 'Danh sách T →' T Trả về giá trị lớn nhất trong số tất cả các phần tử của danh sách, được so sánh bằng cách sử dụng Operator.max.
maxBy: ('T →' U) → 'Danh sách T →' T Trả về giá trị lớn nhất trong số tất cả các phần tử của danh sách, được so sánh bằng cách sử dụng Operator.max trên kết quả hàm.
tối thiểu: 'T danh sách →' T Trả về giá trị thấp nhất trong số tất cả các phần tử của danh sách, được so sánh bằng cách sử dụng Operator.min.
minBy: ('T →' U) → 'T list →' T Trả về giá trị thấp nhất trong số tất cả các phần tử của danh sách, được so sánh bằng cách sử dụng Operator.min trên kết quả hàm
nth: 'T list → int →' T Chỉ mục vào danh sách. Phần tử đầu tiên có chỉ số 0.
ofArray: 'T [] →' Danh sách T Tạo danh sách từ mảng đã cho.
ofSeq: seq <'T> →' T list Tạo danh sách mới từ đối tượng liệt kê đã cho.
phân vùng: ('T → bool) →' Danh sách T * 'Danh sách T Tách tập hợp thành hai tập hợp, chứa các phần tử mà vị từ đã cho trả về truefalse tương ứng.
hoán vị: (int → int) → 'Danh sách T →' Danh sách T Trả về danh sách với tất cả các phần tử được hoán vị theo hoán vị đã chỉ định.
pick: ('T →' U option) → 'T list →' U Áp dụng hàm đã cho cho các phần tử kế tiếp, trả về kết quả đầu tiên trong đó hàm trả về Some cho một số giá trị.
giảm: ('T →' T → 'T) →' Danh sách T → 'T Áp dụng một hàm cho từng phần tử của tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Hàm này áp dụng hàm được chỉ định cho hai phần tử đầu tiên của danh sách. Sau đó, nó chuyển kết quả này vào hàm cùng với phần tử thứ ba, v.v. Cuối cùng, nó trả về kết quả cuối cùng. Nếu hàm đầu vào là f và các phần tử là i0 ... iN, thì hàm này tính f (... (f i0 i1) i2 ...) iN.
ReduceBack: ('T →' T → 'T) →' Danh sách T → 'T Áp dụng một hàm cho từng phần tử của tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Nếu hàm đầu vào làf và các phần tử là i0 ... iN, thì hàm này tính f i0 (... (f iN-1 iN)).
nhân bản: (int → 'T →' T danh sách) Tạo danh sách bằng cách gọi trình tạo đã cho trên mỗi chỉ mục.
rev: 'T list →' T list Trả về một danh sách mới với các phần tử theo thứ tự ngược lại.
quét: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → 'Danh sách T →' Danh sách trạng thái Áp dụng một hàm cho từng phần tử của tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Hàm này nhận đối số thứ hai và áp dụng hàm đã chỉ định cho nó và phần tử đầu tiên của danh sách. Sau đó, nó chuyển kết quả này vào hàm cùng với phần tử thứ hai, v.v. Cuối cùng, nó trả về danh sách các kết quả trung gian và kết quả cuối cùng.
scanBack: ('T →' State → 'State) →' T list → 'State →' State list Giống như foldBack, nhưng trả về cả kết quả trung gian và kết quả cuối cùng
sắp xếp: 'Danh sách T →' Danh sách T Sắp xếp danh sách đã cho bằng Operator.compare.
sortBy: ('T →' Key) → 'T list →' T. list Sắp xếp danh sách đã cho bằng các phím được cung cấp bởi phép chiếu đã cho. Các khóa được so sánh bằng Operator.compare.
sortVới: ('T →' T → int) → 'T list →' T. list Sắp xếp danh sách đã cho bằng chức năng so sánh đã cho.
sum: ^ T danh sách → ^ T Trả về tổng các phần tử trong danh sách.
sumBy: ('T → ^ U) →' T danh sách → ^ U Trả về tổng kết quả được tạo bằng cách áp dụng hàm cho từng phần tử của danh sách.
tail: 'Danh sách T →' Danh sách T Trả về danh sách đầu vào không có phần tử đầu tiên.
toArray: 'T list →' T [] Tạo một mảng từ danh sách đã cho.
toSeq: 'T list → seq <' T> Xem danh sách đã cho dưới dạng một chuỗi.
tryFind: ('T → bool) →' T list → 'T. option Trả về phần tử đầu tiên mà hàm đã cho trả về true. Trở vềNone nếu không có phần tử như vậy tồn tại.
tryFindIndex: ('T → bool) →' T list → int option Trả về chỉ số của phần tử đầu tiên trong danh sách thỏa mãn vị từ đã cho. Trở vềNone nếu không có phần tử như vậy tồn tại.
tryPick: ('T →' U option) → 'T list →' U option Áp dụng hàm đã cho cho các phần tử kế tiếp, trả về kết quả đầu tiên trong đó hàm trả về Somecho một số giá trị. Nếu không có phần tử như vậy tồn tại thì trả vềNone.
giải nén: ('T1 *' T2) danh sách → 'Danh sách T1 *' Danh sách T2 Tách một danh sách các cặp thành hai danh sách.
giải nén3: ('T1 *' T2 * 'T3) danh sách →' Danh sách T1 * 'Danh sách T2 *' Danh sách T3 Tách danh sách bộ ba thành ba danh sách.
zip: 'Danh sách T1 →' Danh sách T2 → ('T1 *' T2) danh sách Kết hợp hai danh sách thành một danh sách các cặp. Hai danh sách phải có độ dài bằng nhau.
zip3: 'Danh sách T1 →' Danh sách T2 → 'Danh sách T3 → (' T1 * 'T2 *' T3) danh sách Kết hợp ba danh sách thành một danh sách bộ ba. Các danh sách phải có độ dài bằng nhau.

Các ví dụ sau đây chứng minh việc sử dụng các chức năng trên:

ví dụ 1

Chương trình này hiển thị việc đảo ngược một danh sách một cách đệ quy -

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1

let reverse lt =
   let rec loop acc = function
      | [] -> acc
      | hd :: tl -> loop (hd :: acc) tl
   loop [] lt

printfn "The reversed list: %A" (reverse list1)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]

Tuy nhiên, bạn có thể sử dụng rev chức năng của mô-đun cho cùng mục đích -

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
printfn "The reversed list: %A" (List.rev list1)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]

Ví dụ 2

Chương trình này hiển thị lọc danh sách bằng cách sử dụng List.filter phương pháp -

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.filter (fun x -> x % 2 = 0);;
printfn "The Filtered list: %A" list2

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Filtered list: [2; 4; 6; 8; 10]

Ví dụ 3

Các List.map phương pháp ánh xạ danh sách từ loại này sang loại khác -

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.map (fun x -> (x * x).ToString());;
printfn "The Mapped list: %A" list2

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Mapped list: ["1"; "4"; "9"; "16"; "25"; "36"; "49"; "64"; "81"; "100"]

Ví dụ 4

Các List.append và toán tử @ nối một danh sách với một danh sách khác -

let list1 = [1; 2; 3; 4; 5 ]
let list2 = [6; 7; 8; 9; 10]
let list3 = List.append list1 list2

printfn "The first list: %A" list1
printfn "The second list: %A" list2
printfn "The appened list: %A" list3

let lt1 = ['a'; 'b';'c' ]
let lt2 = ['e'; 'f';'g' ]
let lt3 = lt1 @ lt2

printfn "The first list: %A" lt1
printfn "The second list: %A" lt2
printfn "The appened list: %A" lt3

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The first list: [1; 2; 3; 4; 5]
The second list: [6; 7; 8; 9; 10]
The appened list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The first list: ['a'; 'b'; 'c']
The second list: ['e'; 'f'; 'g']
The appened list: ['a'; 'b'; 'c'; 'e'; 'f'; 'g']

Ví dụ 5

Các List.sortphương pháp sắp xếp một danh sách. CácList.sum phương thức cung cấp tổng các phần tử trong danh sách và List.average phương pháp cho biết giá trị trung bình của các phần tử trong danh sách -

let list1 = [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
printfn "The list: %A" list1

let list2 = List.sort list1
printfn "The sorted list: %A" list2

let s = List.sum list1
let avg = List.average list1
printfn "The sum: %f" s
printfn "The average: %f" avg

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The list: [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
The sorted list: [-10.0; -4.5; 0.0; 2.0; 8.0; 9.0; 11.2]
The sum: 15.700000
The average: 2.242857

Phép toán "gấp" áp dụng một hàm cho từng phần tử trong danh sách, tổng hợp kết quả của hàm trong một biến tích lũy và trả về bộ tích lũy là kết quả của thao tác gấp.

Ví dụ 6

Các List.fold phương thức áp dụng một hàm cho từng phần tử từ trái sang phải, trong khi List.foldBack áp dụng một chức năng cho mỗi phần tử từ phải sang trái.

let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 10 ] (sumList [ 1 .. 10 ])

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.

Chuỗi, giống như danh sách cũng đại diện cho một tập hợp các giá trị có thứ tự. Tuy nhiên, các phần tử trong một chuỗi hoặc biểu thức chuỗi được tính toán khi được yêu cầu. Chúng không được tính toán cùng một lúc và vì lý do này, chúng được sử dụng để biểu diễn cấu trúc dữ liệu vô hạn.

Xác định trình tự

Các chuỗi được xác định bằng cú pháp sau:

seq { expr }

Ví dụ,

let seq1 = seq { 1 .. 10 }

Tạo chuỗi và biểu thức chuỗi

Tương tự như danh sách, bạn có thể tạo chuỗi bằng cách sử dụng phạm vi và khả năng hiểu.

Biểu thức trình tự là những biểu thức bạn có thể viết để tạo chuỗi. Những điều này có thể được thực hiện -

  • Bằng cách chỉ định phạm vi.
  • Bằng cách chỉ định phạm vi với mức tăng hoặc giảm.
  • Bằng cách sử dụng yield từ khóa để tạo ra các giá trị trở thành một phần của chuỗi.
  • Bằng cách sử dụng toán tử →.

Các ví dụ sau đây chứng minh khái niệm -

ví dụ 1

(* Sequences *)
let seq1 = seq { 1 .. 10 }

(* ascending order and increment*)
printfn "The Sequence: %A" seq1
let seq2 = seq { 1 .. 5 .. 50 }

(* descending order and decrement*)
printfn "The Sequence: %A" seq2
let seq3 = seq {50 .. -5 .. 0}
printfn "The Sequence: %A" seq3

(* using yield *)
let seq4 = seq { for a in 1 .. 10 do yield a, a*a, a*a*a }
printfn "The Sequence: %A" seq4

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The Sequence: seq [1; 2; 3; 4; ...]
The Sequence: seq [1; 6; 11; 16; ...]
The Sequence: seq [50; 45; 40; 35; ...]
The Sequence: seq [(1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64); ...]

Ví dụ 2

Chương trình sau đây in ra các số nguyên tố từ 1 đến 50:

(* Recursive isprime function. *)
let isprime n =
   let rec check i =
      i > n/2 || (n % i <> 0 && check (i + 1))
   check 2

let primeIn50 = seq { for n in 1..50 do if isprime n then yield n }
for x in primeIn50 do
   printfn "%d" x

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

1
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47

Các thao tác cơ bản trên trình tự

Bảng sau đây trình bày các thao tác cơ bản trên kiểu dữ liệu trình tự

Giá trị Sự miêu tả
nối thêm: seq <'T> → seq <' T> → seq <'T> Bao bọc hai kiểu liệt kê đã cho dưới dạng một kiểu liệt kê nối liền nhau.
trung bình: seq <^ T> → ^ T Trả về giá trị trung bình của các phần tử trong dãy.
AverageBy: ('T → ^ U) → seq <' T> → ^ U Trả về giá trị trung bình của các kết quả được tạo bằng cách áp dụng hàm cho từng phần tử của dãy.
cache: seq <'T> → seq <' T> Trả về một chuỗi tương ứng với phiên bản được lưu trong bộ nhớ cache của chuỗi đầu vào.
diễn viên: IEnumerable → seq <'T> Bao bọc một Hệ thống được đánh máy lỏng lẻo. Trình tự tập hợp dưới dạng trình tự đã nhập.
chọn: ('T →' U option) → seq <'T> → seq <' U> Áp dụng chức năng đã cho cho từng phần tử của danh sách. Trả về danh sách bao gồm các kết quả cho từng phần tử mà hàm trả vềSome.
thu thập: ('T →' Tập hợp) → seq <'T> → seq <' U> Áp dụng hàm đã cho cho từng phần tử của dãy và nối tất cả các kết quả.
so sánhVới: ('T →' T → int) → seq <'T> → seq <' T> → int So sánh hai chuỗi bằng cách sử dụng chức năng so sánh đã cho, từng phần tử.
concat: seq <'Bộ sưu tập> → seq <' T> Kết hợp các kiểu liệt kê đã cho dưới dạng một kiểu liệt kê nối đơn lẻ.
countBy: ('T →' Key) → seq <'T> → seq <' Key * int> Áp dụng chức năng tạo khóa cho từng phần tử của một chuỗi và trả về một chuỗi mang lại các khóa duy nhất và số lần xuất hiện của chúng trong chuỗi ban đầu.
delay: (unit → seq <'T>) → seq <' T> Trả về một trình tự được xây dựng từ đặc điểm kỹ thuật bị trễ đã cho của một trình tự.
khác biệt: seq <'T> → seq <' T> Trả về một chuỗi không chứa mục nhập trùng lặp theo phép so sánh hàm băm và đẳng thức chung trên các mục nhập. Nếu một phần tử xuất hiện nhiều lần trong chuỗi thì các phần tử xuất hiện sau đó sẽ bị loại bỏ.
Riêng biệtBy: ('T →' Phím) → seq <'T> → seq <' T> Trả về một chuỗi không chứa mục nhập trùng lặp theo phép so sánh hàm băm và đẳng thức chung trên các khóa được trả về bởi hàm tạo khóa đã cho. Nếu một phần tử xuất hiện nhiều lần trong chuỗi thì các phần tử xuất hiện sau đó sẽ bị loại bỏ.
trống: seq <'T> Tạo một chuỗi trống.
chính xácOne: seq <'T> →' T Trả về phần tử duy nhất của dãy.
tồn tại: ('T → bool) → seq <' T> → bool Kiểm tra xem có phần tử nào của dãy thỏa mãn vị từ đã cho hay không.
tồn tại2: ('T1 →' T2 → bool) → seq <'T1> → seq <' T2> → bool Kiểm tra xem có cặp phần tử tương ứng nào của chuỗi đầu vào thỏa mãn vị từ đã cho hay không.
bộ lọc: ('T → bool) → seq <' T> → seq <'T> Trả về một tập hợp mới chỉ chứa các phần tử của tập hợp mà vị từ đã cho trả về true.
find: ('T → bool) → seq <' T> → 'T Trả về phần tử đầu tiên mà hàm đã cho trả về true.
findIndex: ('T → bool) → seq <' T> → int Trả về chỉ mục của phần tử đầu tiên mà hàm đã cho trả về true.
gấp: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → seq <'T> →' Trạng thái Áp dụng một hàm cho từng phần tử của tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Nếu hàm đầu vào là f và các phần tử là i0 ... iN, thì hàm này tính f (... (fs i0) ...) iN.
forall: ('T → bool) → seq <' T> → bool Kiểm tra xem tất cả các phần tử của dãy có thỏa mãn vị từ đã cho hay không.
forall2: ('T1 →' T2 → bool) → seq <'T1> → seq <' T2> → bool Kiểm tra tất cả các cặp phần tử được rút ra từ hai dãy thỏa mãn vị từ đã cho. Nếu một dãy ngắn hơn dãy kia thì các phần tử còn lại của dãy dài hơn bị bỏ qua.
groupBy: ('T →' Key) → seq <'T> → seq <' Key * seq <'T >> Áp dụng chức năng tạo khóa cho từng phần tử của một chuỗi và tạo ra một chuỗi các khóa duy nhất. Mỗi khóa duy nhất cũng chứa một chuỗi tất cả các phần tử khớp với khóa này.
head: seq <'T> →' T Trả về phần tử đầu tiên của dãy.
init: int → (int → 'T) → seq <' T> Tạo một chuỗi mới, khi được lặp lại, trả về các phần tử liên tiếp bằng cách gọi hàm đã cho, với số lượng đã cho. Kết quả của việc gọi hàm không được lưu, tức là, hàm được áp dụng lại khi cần thiết để tạo lại các phần tử. Hàm được chuyển chỉ mục của mục được tạo.
initInfinite: (int → 'T) → seq <' T> Tạo một chuỗi mới, khi được lặp lại, sẽ trả về các phần tử kế tiếp bằng cách gọi hàm đã cho. Kết quả của việc gọi hàm không được lưu, tức là, hàm sẽ được áp dụng lại khi cần thiết để tạo lại các phần tử. Hàm được chuyển chỉ mục của mục được tạo.
isEmpty: seq <'T> → bool Kiểm tra xem một chuỗi có bất kỳ phần tử nào không.
iter: ('T → đơn vị) → seq <' T> → đơn vị Áp dụng chức năng đã cho cho từng phần tử của tập hợp.
iter2: ('T1 →' T2 → đơn vị) → seq <'T1> → seq <' T2> → đơn vị Áp dụng chức năng đã cho cho hai tập hợp đồng thời. Nếu một dãy ngắn hơn dãy kia thì các phần tử còn lại của dãy dài hơn bị bỏ qua.
iteri: (int → 'T → đơn vị) → seq <' T> → đơn vị Áp dụng chức năng đã cho cho từng phần tử của tập hợp. Số nguyên được truyền vào hàm cho biết chỉ số của phần tử.
cuối cùng: seq <'T> →' T Trả về phần tử cuối cùng của dãy.
length: seq <'T> → int Trả về độ dài của chuỗi.
map: ('T →' U) → seq <'T> → seq <' U> Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho từng phần tử của tập hợp. Hàm đã cho sẽ được áp dụng khi các phần tử được yêu cầu bằng cách sử dụng phương thức MoveNext trên các liệt kê được truy xuất từ ​​đối tượng.
map2: ('T1 →' T2 → 'U) → seq <' T1> → seq <'T2> → seq <' U> Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho các cặp phần tử tương ứng từ hai chuỗi. Nếu một chuỗi đầu vào ngắn hơn chuỗi đầu vào kia thì các phần tử còn lại của chuỗi dài hơn sẽ bị bỏ qua.
mapi: (int → 'T →' U) → seq <'T> → seq <' U> Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho từng phần tử của tập hợp. Chỉ số số nguyên được chuyển đến hàm cho biết chỉ số (từ 0) của phần tử được chuyển đổi.
tối đa: seq <'T> →' T Trả về giá trị lớn nhất trong số tất cả các phần tử của dãy, được so sánh bằng cách sử dụng Operator.max.
maxBy: ('T →' U) → seq <'T> →' T Trả về giá trị lớn nhất trong số tất cả các phần tử của dãy, được so sánh bằng cách sử dụng Operator.max trên kết quả hàm.
tối thiểu: seq <'T> →' T Trả về giá trị thấp nhất trong số tất cả các phần tử của dãy, được so sánh bằng cách sử dụng Operator.min.
minBy: ('T →' U) → seq <'T> →' T Trả về giá trị thấp nhất trong số tất cả các phần tử của dãy, được so sánh bằng cách sử dụng Operator.min trên kết quả của hàm.
thứ n: int → seq <'T> →' T Tính toán phần tử thứ n trong tập hợp.
ofArray: 'T mảng → seq <' T> Xem mảng đã cho dưới dạng một chuỗi.
ofList: 'T list → seq <' T> Xem danh sách đã cho dưới dạng một chuỗi.
theo cặp: seq <'T> → seq <' T * 'T> Trả về một chuỗi của mỗi phần tử trong chuỗi đầu vào và phần tử tiền nhiệm của nó, ngoại trừ phần tử đầu tiên chỉ được trả về như phần tử trước của phần tử thứ hai.
pick: ('T →' U option) → seq <'T> →' U Áp dụng hàm đã cho cho các phần tử kế tiếp, trả về giá trị đầu tiên trong đó hàm trả về Some giá trị.
chỉ đọc: seq <'T> → seq <' T> Tạo một đối tượng chuỗi mới ủy quyền cho đối tượng chuỗi đã cho. Điều này đảm bảo trình tự ban đầu không thể được khám phá lại và biến đổi bởi một kiểu đúc. Ví dụ: nếu cho một mảng, chuỗi được trả về sẽ trả về các phần tử của mảng, nhưng bạn không thể ép kiểu đối tượng chuỗi được trả về vào một mảng.
giảm: ('T →' T → 'T) → seq <' T> → 'T Áp dụng một hàm cho mỗi phần tử của chuỗi, xâu chuỗi một đối số tích lũy thông qua tính toán. Bắt đầu bằng cách áp dụng hàm cho hai phần tử đầu tiên. Sau đó, cung cấp kết quả này vào hàm cùng với phần tử thứ ba, v.v. Trả lại kết quả cuối cùng.
quét: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → seq <'T> → seq <' Trạng thái> Giống như Seq.fold, nhưng tính toán theo yêu cầu và trả về chuỗi kết quả trung gian và cuối cùng.
singleton: 'T → seq <' T> Trả về một chuỗi chỉ mang lại một mục.
bỏ qua: int → seq <'T> → seq <' T> Trả về một chuỗi bỏ qua một số phần tử được chỉ định của chuỗi bên dưới và sau đó trả về các phần tử còn lại của chuỗi.
bỏ quaWhile: ('T → bool) → seq <' T> → seq <'T> Trả về một chuỗi mà khi được lặp lại, bỏ qua các phần tử của chuỗi cơ bản trong khi vị từ đã cho trả về true, và sau đó thu được các phần tử còn lại của dãy.
sắp xếp: seq <'T> → seq <' T> Mang lại một chuỗi được sắp xếp theo các phím.
sortBy: ('T →' Key) → seq <'T> → seq <' T> Áp dụng chức năng tạo khóa cho từng phần tử của một chuỗi và mang lại một chuỗi được sắp xếp theo các khóa. Các khóa được so sánh bằng cách sử dụng so sánh chung như được triển khai bởi Operators.compare.
tổng: seq <^ T> → ^ T Trả về tổng các phần tử trong dãy.
sumBy Trả về tổng các kết quả được tạo ra bằng cách áp dụng hàm cho từng phần tử của dãy.
lấy: int → seq <'T> → seq <' T> Trả về các phần tử đầu tiên của dãy với số lượng được chỉ định.
takeWhile: ('T → bool) → seq <' T> → seq <'T> Trả về một chuỗi mà khi được lặp lại, sẽ mang lại các phần tử của chuỗi bên dưới trong khi vị từ đã cho trả về true, và sau đó không trả về phần tử nào nữa.
toArray: seq <'T> →' T [] Tạo một mảng từ bộ sưu tập đã cho.
toList: seq <'T> →' T list Tạo danh sách từ bộ sưu tập đã cho.
cắt ngắn: int → seq <'T> → seq <' T> Trả về một chuỗi mà khi được liệt kê trả về không quá một số phần tử được chỉ định.
tryFind: ('T → bool) → seq <' T> → 'T tùy chọn Trả về phần tử đầu tiên mà hàm đã cho trả về true, hoặc là None nếu không có phần tử như vậy tồn tại.
tryFindIndex: ('T → bool) → seq <' T> → int option Trả về chỉ số của phần tử đầu tiên trong chuỗi thỏa mãn vị từ đã cho, hoặc None nếu không có phần tử như vậy tồn tại.
tryPick: ('T →' U option) → seq <'T> →' U option Áp dụng hàm đã cho cho các phần tử kế tiếp, trả về giá trị đầu tiên trong đó hàm trả về Some giá trị.
mở ra: ('Trạng thái →' T * 'Tùy chọn trạng thái) →' Trạng thái → seq <'T> Trả về một chuỗi chứa các phần tử được tạo bởi phép tính đã cho.
trong đó: ('T → bool) → seq <' T> → seq <'T> Trả về một tập hợp mới chỉ chứa các phần tử của tập hợp mà vị từ đã cho trả về true. Một từ đồng nghĩa với Seq.filter.
windowed: int → seq <'T> → seq <' T []> Trả về một chuỗi mang lại cửa sổ trượt chứa các phần tử được vẽ từ chuỗi đầu vào. Mỗi cửa sổ được trả về dưới dạng một mảng mới.
zip: seq <'T1> → seq <' T2> → seq <'T1 *' T2> Kết hợp hai chuỗi thành một danh sách các cặp. Hai trình tự không nhất thiết phải có độ dài bằng nhau - khi một trình tự cạn kiệt thì bất kỳ phần tử còn lại nào trong trình tự khác sẽ bị bỏ qua.
zip3: seq <'T1> → seq <' T2> → seq <'T3> → seq <' T1 * 'T2 *' T3> Kết hợp ba chuỗi thành một danh sách các bộ ba. Các trình tự không cần phải có độ dài bằng nhau - khi một trình tự sử dụng hết, bất kỳ phần tử còn lại nào trong các trình tự khác sẽ bị bỏ qua.

Các ví dụ sau đây chứng minh việc sử dụng một số chức năng ở trên -

ví dụ 1

Chương trình này tạo một chuỗi trống và lấp đầy nó sau -

(* Creating sequences *)
let emptySeq = Seq.empty
let seq1 = Seq.singleton 20

printfn"The singleton sequence:"
printfn "%A " seq1
printfn"The init sequence:"

let seq2 = Seq.init 5 (fun n -> n * 3)
Seq.iter (fun i -> printf "%d " i) seq2
printfn""

(* converting an array to sequence by using cast *)
printfn"The array sequence 1:"
let seq3 = [| 1 .. 10 |] :> seq<int>
Seq.iter (fun i -> printf "%d " i) seq3
printfn""

(* converting an array to sequence by using Seq.ofArray *)
printfn"The array sequence 2:"
let seq4 = [| 2..2.. 20 |] |> Seq.ofArray
Seq.iter (fun i -> printf "%d " i) seq4
printfn""

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The singleton sequence:
seq [20]
The init sequence:
0 3 6 9 12
The array sequence 1:
1 2 3 4 5 6 7 8 9 10
The array sequence 2:
2 4 6 8 10 12 14 16 18 20

Xin lưu ý rằng -

  • Phương thức Seq.empty tạo ra một chuỗi trống.

  • Phương thức Seq.singleton tạo ra một chuỗi chỉ gồm một phần tử được chỉ định.

  • Phương thức Seq.init tạo ra một chuỗi mà các phần tử được tạo bằng cách sử dụng một hàm đã cho.

  • Phương thức Seq.ofArray và Seq.ofList <'T> tạo chuỗi từ mảng và danh sách.

  • Phương thức Seq.iter cho phép lặp qua một chuỗi.

Ví dụ 2

Phương thức Seq.unfold tạo ra một chuỗi từ một hàm tính toán có trạng thái và biến đổi nó để tạo ra từng phần tử tiếp theo trong chuỗi.

Hàm sau tạo ra 20 số tự nhiên đầu tiên:

let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20."
for x in seq1 do printf "%d " x
printfn" "

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The sequence seq1 contains numbers from 0 to 20.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Ví dụ 3

Phương thức Seq.truncate tạo một chuỗi từ một chuỗi khác, nhưng giới hạn chuỗi ở một số phần tử xác định.

Phương thức Seq.take tạo ra một chuỗi mới có chứa một số phần tử được chỉ định từ đầu chuỗi.

let mySeq = seq { for i in 1 .. 10 -> 3*i }
let truncatedSeq = Seq.truncate 5 mySeq
let takeSeq = Seq.take 5 mySeq

printfn"The original sequence"
Seq.iter (fun i -> printf "%d " i) mySeq
printfn""

printfn"The truncated sequence"
Seq.iter (fun i -> printf "%d " i) truncatedSeq
printfn""

printfn"The take sequence"
Seq.iter (fun i -> printf "%d " i) takeSeq
printfn""

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The original sequence
3 6 9 12 15 18 21 24 27 30
The truncated sequence
3 6 9 12 15
The take sequence
3 6 9 12 15

Một tập hợp trong F # là một cấu trúc dữ liệu hoạt động như một tập hợp các mục mà không bảo toàn thứ tự các mục được chèn vào. Bộ không cho phép chèn các mục trùng lặp vào bộ sưu tập.

Tạo bộ

Bộ có thể được tạo theo những cách sau:

  • Bằng cách tạo một tập hợp trống bằng Set.empty và thêm các mục bằng chức năng thêm.
  • Chuyển đổi chuỗi và danh sách thành tập hợp.

Chương trình sau đây trình bày các kỹ thuật -

(* creating sets *)
let set1 = Set.empty.Add(3).Add(5).Add(7). Add(9)
printfn"The new set: %A" set1

let weekdays = Set.ofList ["mon"; "tues"; "wed"; "thurs"; "fri"]
printfn "The list set: %A" weekdays

let set2 = Set.ofSeq [ 1 .. 2.. 10 ]
printfn "The sequence set: %A" set2

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The new set: set [3; 5; 7; 9]
The list set: set ["fri"; "mon"; "thurs"; "tues"; "wed"]
The sequence set: set [1; 3; 5; 7; 9]

Các thao tác cơ bản trên bộ

Bảng sau đây cho thấy các hoạt động cơ bản trên các tập hợp:

Giá trị Sự miêu tả
thêm: 'T → Đặt <' T> → Đặt <'T> Trả về một tập hợp mới với một phần tử được thêm vào tập hợp. Không có ngoại lệ nào được nêu ra nếu tập hợp đã chứa phần tử đã cho.
chứa: 'T → Đặt <' T> → bool Đánh giá để true nếu phần tử đã cho nằm trong tập hợp đã cho.
count: Đặt <'T> → int Trả về số phần tử trong tập hợp.
khác biệt: Đặt <'T> → Đặt <' T> → Đặt <'T> Trả về một tập hợp mới với các phần tử của tập hợp thứ hai bị xóa khỏi tập hợp đầu tiên.
trống: Đặt <'T> Tập hợp trống cho loại được chỉ định.
tồn tại: ('T → bool) → Đặt <' T> → bool Kiểm tra xem có phần tử nào của tập hợp thỏa mãn vị từ đã cho hay không. Nếu hàm đầu vào là vị từ và các phần tử là i0 ... iN, thì hàm này sẽ tính vị từ i0 hoặc ... hoặc vị từ iN.
bộ lọc: ('T → bool) → Đặt <' T> → Đặt <'T> Trả về một tập hợp mới chỉ chứa các phần tử của tập hợp mà vị từ đã cho trả về true.
gấp: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → Đặt <'T> →' Trạng thái Áp dụng hàm tích lũy đã cho cho tất cả các phần tử của tập hợp.
gấp lại: ('T →' Trạng thái → 'Trạng thái) → Đặt <' T> → 'Trạng thái →' Trạng thái Áp dụng hàm tích lũy đã cho cho tất cả các phần tử của tập hợp.
forall: ('T → bool) → Đặt <' T> → bool Kiểm tra xem tất cả các phần tử của tập hợp có thỏa mãn vị từ đã cho hay không. Nếu hàm đầu vào là p và các phần tử là i0 ... iN, thì hàm này tính p i0 && ... && p iN.
giao nhau: Đặt <'T> → Đặt <' T> → Đặt <'T> Tính giao của hai tập hợp.
Giao nhau Nhiều: seq <Đặt <'T >> → Đặt <' T> Tính toán giao của một dãy các tập hợp. Trình tự không được để trống.
isEmpty: Đặt <'T> → bool Lợi nhuận true nếu tập hợp trống.
isProperSubset: Đặt <'T> → Đặt <' T> → bool Đánh giá để true nếu tất cả các phần tử của tập hợp đầu tiên nằm trong tập hợp thứ hai và ít nhất một phần tử của tập hợp thứ hai không nằm trong tập hợp thứ nhất.
isProperSuperset: Đặt <'T> → Đặt <' T> → bool Đánh giá để true nếu tất cả các phần tử của tập hợp thứ hai nằm trong tập hợp thứ nhất và ít nhất một phần tử của tập hợp thứ nhất không nằm trong tập hợp thứ hai.
isSubset: Đặt <'T> → Đặt <' T> → bool Đánh giá để true nếu tất cả các phần tử của tập thứ nhất nằm trong tập thứ hai.
isSuperset: Đặt <'T> → Đặt <' T> → bool Đánh giá để true nếu tất cả các phần tử của tập thứ hai nằm trong tập thứ nhất.
iter: ('T → đơn vị) → Đặt <' T> → đơn vị Áp dụng hàm đã cho cho từng phần tử của tập hợp, theo thứ tự theo hàm so sánh.
map: ('T →' U) → Đặt <'T> → Đặt <' U> Trả về một tập hợp mới chứa kết quả của việc áp dụng hàm đã cho cho từng phần tử của tập đầu vào.
maxElement: Đặt <'T> →' T Trả về phần tử cao nhất trong tập hợp theo thứ tự đang được sử dụng cho tập hợp.
minElement: Đặt <'T> →' T Trả về phần tử thấp nhất trong tập hợp theo thứ tự đang được sử dụng cho tập hợp.
ofArray: 'T mảng → Đặt <' T> Tạo một tập hợp chứa các phần tử giống như mảng đã cho.
ofList: 'T list → Set <' T> Tạo một tập hợp chứa các phần tử giống như danh sách đã cho.
ofSeq: seq <'T> → Đặt <' T> Tạo một bộ sưu tập mới từ đối tượng liệt kê đã cho.
phân vùng: ('T → bool) → Đặt <' T> → Đặt <'T> * Đặt <' T> Tách tập hợp thành hai tập hợp chứa các phần tử mà vị từ đã cho trả về giá trị true và false tương ứng.
loại bỏ: 'T → Đặt <' T> → Đặt <'T> Trả về một tập hợp mới với phần tử đã cho đã bị xóa. Không có ngoại lệ nào được nêu ra nếu tập hợp không chứa phần tử đã cho.
singleton: 'T → Đặt <' T> Tập hợp chứa phần tử đã cho.
toArray: Đặt mảng <'T> →' T Tạo một mảng có chứa các phần tử của tập hợp theo thứ tự.
toList: Đặt <'T> →' T list Tạo một danh sách có chứa các phần tử của tập hợp theo thứ tự.
toSeq: Đặt <'T> → seq <' T> Trả về dạng xem có thứ tự của tập hợp dưới dạng một đối tượng có thể liệt kê.
union: Đặt <'T> → Đặt <' T> → Đặt <'T> Tính toán hợp nhất của hai tập hợp.
unionMany: seq <Đặt <'T >> → Đặt <' T> Tính toán hợp nhất của một chuỗi các tập hợp.

Ví dụ sau minh họa việc sử dụng một số chức năng trên:

Thí dụ

let a = Set.ofSeq [ 1 ..2.. 20 ]
let b = Set.ofSeq [ 1 ..3 .. 20 ]
let c = Set.intersect a b
let d = Set.union a b
let e = Set.difference a b

printfn "Set a: "
Set.iter (fun x -> printf "%O " x) a
printfn""

printfn "Set b: "
Set.iter (fun x -> printf "%O " x) b
printfn""

printfn "Set c = set intersect of a and b : "
Set.iter (fun x -> printf "%O " x) c
printfn""

printfn "Set d = set union of a and b : "
Set.iter (fun x -> printf "%O " x) d
printfn""

printfn "Set e = set difference of a and b : "
Set.iter (fun x -> printf "%O " x) e
printfn""

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Set a:
1 3 5 7 9 11 13 15 17 19
Set b:
1 4 7 10 13 16 19
Set c = set intersect of a and b :
1 7 13 19
Set d = set union of a and b :
1 3 4 5 7 9 10 11 13 15 16 17 19
Set e = set difference of a and b :
3 5 9 11 15 17

Trong F #, bản đồ là một loại tập hợp đặc biệt liên kết các giá trị với khóa. Một bản đồ được tạo theo cách tương tự như các tập hợp được tạo.

Tạo bản đồ

Bản đồ được tạo bằng cách tạo một bản đồ trống bằng Map.empty và thêm các mục bằng chức năng Thêm. Ví dụ sau đây chứng minh điều này -

Thí dụ

(* Create an empty Map *)
let students =
   Map.empty. (* Creating an empty Map *)
      Add("Zara Ali", "1501").
      Add("Rishita Gupta", "1502").
      Add("Robin Sahoo", "1503").
      Add("Gillian Megan", "1504");;
printfn "Map - students: %A" students

(* Convert a list to Map *)
let capitals =
   [ "Argentina", "Buenos Aires";
      "France ", "Paris";
      "Chili", "Santiago";
      "Malaysia", " Kuala Lumpur";
      "Switzerland", "Bern" ]
   |> Map.ofList;;
printfn "Map capitals : %A" capitals

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Map - students: map
[("Gillian Megan", "1504"); ("Rishita Gupta", "1502"); ("Robin Sahoo", "1503
");
("Zara Ali", "1501")]
Map capitals : map
[("Argentina", "Buenos Aires"); ("Chili", "Santiago"); ("France ", "Paris");
("Malaysia", " Kuala Lumpur"); ("Switzerland", "Bern")]

Bạn có thể truy cập các yếu tố riêng lẻ trong bản đồ bằng cách sử dụng phím.

Thí dụ

(* Create an empty Map *)
let students =
   Map.empty. (* Creating an empty Map *)
      Add("Zara Ali", "1501").
      Add("Rishita Gupta", "1502").
      Add("Robin Sahoo", "1503").
      Add("Gillian Megan", "1504");;
printfn "Map - students: %A" students

(*Accessing an element using key *)
printfn "%A" students.["Zara Ali"]

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Map - students: map
[("Gillian Megan", "1504"); ("Rishita Gupta", "1502"); ("Robin Sahoo", "1503
");
("Zara Ali", "1501")]
"1501"

Các thao tác cơ bản trên Bản đồ

Thêm tên mô-đun

Bảng sau đây trình bày các thao tác cơ bản trên bản đồ:

Thành viên Sự miêu tả
Thêm vào Trả về một bản đồ mới với ràng buộc được thêm vào bản đồ đã cho.
ContainsKey Kiểm tra xem một phần tử có trong miền của bản đồ hay không.
Đếm Số lượng ràng buộc trong bản đồ.
IsEmpty Trả về true nếu không có ràng buộc nào trong bản đồ.
Mục Tra cứu một phần tử trong bản đồ. Tăng KeyNotFoundException nếu không có ràng buộc nào tồn tại trong bản đồ.
Tẩy Xóa một phần tử khỏi miền của bản đồ. Không có ngoại lệ nào được nêu ra nếu phần tử không có mặt.
TryFind Tra cứu một phần tử trong bản đồ, trả về Some giá trị nếu phần tử nằm trong miền của bản đồ và None nếu không.

Ví dụ sau minh họa việc sử dụng một số chức năng trên:

Thí dụ

(* Create an empty Map *)
let students =
   Map.empty. (* Creating an empty Map *)
      Add("Zara Ali", "1501").
      Add("Rishita Gupta", "1502").
      Add("Robin Sahoo", "1503").
      Add("Gillian Megan", "1504").
      Add("Shraddha Dubey", "1505").
      Add("Novonil Sarker", "1506").
      Add("Joan Paul", "1507");;
printfn "Map - students: %A" students
printfn "Map - number of students: %d" students.Count

(* finding the registration number of a student*)
let found = students.TryFind "Rishita Gupta"
match found with
| Some x -> printfn "Found %s." x
| None -> printfn "Did not find the specified value."

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Map - students: map
[("Gillian Megan", "1504"); ("Joan Paul", "1507"); ("Novonil Sarker", "1506"
);
("Rishita Gupta", "1502"); ("Robin Sahoo", "1503");
("Shraddha Dubey", "1505"); ("Zara Ali", "1501")]
Map - number of students: 7
Found 1502.

Công đoàn, hoặc công đoàn phân biệt đối xử cho phép bạn xây dựng cấu trúc dữ liệu phức tạp đại diện cho tập hợp các lựa chọn được xác định rõ. Ví dụ: bạn cần xây dựng một triển khai của một biến lựa chọn , biến này có hai giá trị có và không. Sử dụng công cụ Unions, bạn có thể thiết kế điều này.

Cú pháp

Các công đoàn phân biệt đối xử được định nghĩa bằng cú pháp sau:

type type-name =
   | case-identifier1 [of [ fieldname1 : ] type1 [ * [ fieldname2 : ] 
type2 ...]
   | case-identifier2 [of [fieldname3 : ]type3 [ * [ fieldname4 : ]type4 ...]
...

Cách triển khai đơn giản của chúng tôi về, sự lựa chọn, sẽ giống như sau:

type choice =
   | Yes
   | No

Ví dụ sau sử dụng lựa chọn kiểu:

type choice =
   | Yes
   | No

let x = Yes (* creates an instance of choice *)
let y = No (* creates another instance of choice *)
let main() =
   printfn "x: %A" x
   printfn "y: %A" y
main()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

x: Yes
y: No

ví dụ 1

Ví dụ sau đây cho thấy việc triển khai các trạng thái điện áp đặt một chút ở mức cao hoặc thấp -

type VoltageState =
   | High
   | Low

let toggleSwitch = function (* pattern matching input *)
   | High -> Low
   | Low -> High

let main() =
   let on = High
   let off = Low
   let change = toggleSwitch off

   printfn "Switch on state: %A" on
   printfn "Switch off state: %A" off
   printfn "Toggle off: %A" change
   printfn "Toggle the Changed state: %A" (toggleSwitch change)

main()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Switch on state: High
Switch off state: Low
Toggle off: High
Toggle the Changed state: Low

Ví dụ 2

type Shape =
   // here we store the radius of a circle
   | Circle of float

   // here we store the side length.
   | Square of float

   // here we store the height and width.
   | Rectangle of float * float

let pi = 3.141592654

let area myShape =
   match myShape with
   | Circle radius -> pi * radius * radius
   | Square s -> s * s
   | Rectangle (h, w) -> h * w

let radius = 12.0
let myCircle = Circle(radius)
printfn "Area of circle with radius %g: %g" radius (area myCircle)

let side = 15.0
let mySquare = Square(side)
printfn "Area of square that has side %g: %g" side (area mySquare)

let height, width = 5.0, 8.0
let myRectangle = Rectangle(height, width)
printfn "Area of rectangle with height %g and width %g is %g" height width (area myRectangle)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Area of circle with radius 12: 452.389
Area of square that has side 15: 225
Area of rectangle with height 5 and width 8 is 40

Các biến trong F # là immutable,có nghĩa là một khi một biến được liên kết với một giá trị, nó sẽ không thể thay đổi được. Chúng thực sự được biên dịch dưới dạng thuộc tính chỉ đọc tĩnh.

Ví dụ sau đây chứng minh điều này.

Thí dụ

let x = 10
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

let x = 15
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

Khi bạn biên dịch và thực thi chương trình, nó hiển thị thông báo lỗi sau:

Duplicate definition of value 'x'
Duplicate definition of value 'Y'
Duplicate definition of value 'Z'

Các biến có thể thay đổi

Đôi khi bạn cần thay đổi các giá trị được lưu trữ trong một biến. Để xác định rằng có thể có sự thay đổi giá trị của một biến được khai báo và gán trong phần sau của chương trình, F # cung cấpmutabletừ khóa. Bạn có thể khai báo và gán các biến có thể thay đổi bằng cách sử dụng từ khóa này, các giá trị của chúng mà bạn sẽ thay đổi.

Các mutable từ khóa cho phép bạn khai báo và gán giá trị trong một biến có thể thay đổi.

Bạn có thể gán một số giá trị ban đầu cho một biến có thể thay đổi bằng cách sử dụng lettừ khóa. Tuy nhiên, để gán giá trị tiếp theo mới cho nó, bạn cần sử dụng<- nhà điều hành.

Ví dụ,

let mutable x = 10
x <- 15

Ví dụ sau sẽ rõ ràng khái niệm -

Thí dụ

let mutable x = 10
let y = 20
let mutable z = x + y

printfn "Original Values:"
printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

printfn "Let us change the value of x"
printfn "Value of z will change too."

x <- 15
z <- x + y

printfn "New Values:"
printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Original Values:
x: 10
y: 20
z: 30
Let us change the value of x
Value of z will change too.
New Values:
x: 15
y: 20
z: 35

Sử dụng dữ liệu có thể thay đổi

Dữ liệu có thể thay đổi thường được yêu cầu và sử dụng trong xử lý dữ liệu, đặc biệt là với cấu trúc dữ liệu bản ghi. Ví dụ sau đây chứng minh điều này -

open System

type studentData =
   { ID : int;
      mutable IsRegistered : bool;
      mutable RegisteredText : string; }

let getStudent id =
   { ID = id;
      IsRegistered = false;
      RegisteredText = null; }

let registerStudents (students : studentData list) =
   students |> List.iter(fun st ->
      st.IsRegistered <- true
      st.RegisteredText <- sprintf "Registered %s" (DateTime.Now.ToString("hh:mm:ss"))

      Threading.Thread.Sleep(1000) (* Putting thread to sleep for 1 second to simulate processing overhead. *))

let printData (students : studentData list) =
   students |> List.iter (fun x -> printfn "%A" x)

let main() =
   let students = List.init 3 getStudent

   printfn "Before Process:"
   printData students

   printfn "After process:"
   registerStudents students
   printData students

   Console.ReadKey(true) |> ignore

main()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Before Process:
{ID = 0;
IsRegistered = false;
RegisteredText = null;}
{ID = 1;
IsRegistered = false;
RegisteredText = null;}
{ID = 2;
IsRegistered = false;
RegisteredText = null;}
After process:
{ID = 0;
IsRegistered = true;
RegisteredText = "Registered 05:39:15";}
{ID = 1;
IsRegistered = true;
RegisteredText = "Registered 05:39:16";}
{ID = 2;
IsRegistered = true;
RegisteredText = "Registered 05:39:17";}

Mảng là tập hợp có kích thước cố định, dựa trên 0, có thể thay đổi của các phần tử dữ liệu liên tiếp có cùng kiểu.

Tạo Mảng

Bạn có thể tạo mảng bằng các cú pháp và cách khác nhau hoặc bằng cách sử dụng các hàm từ mô-đun Mảng. Trong phần này, chúng ta sẽ thảo luận về việc tạo mảng mà không cần sử dụng các hàm mô-đun.

Có ba cách cú pháp để tạo mảng không có hàm:

  • Bằng cách liệt kê các giá trị liên tiếp giữa [| và |] và được phân tách bằng dấu chấm phẩy.
  • Bằng cách đặt mỗi phần tử trên một dòng riêng biệt, trong trường hợp đó dấu phân tách bằng dấu chấm phẩy là tùy chọn.
  • Bằng cách sử dụng các biểu thức trình tự.

Bạn có thể truy cập các phần tử của mảng bằng cách sử dụng toán tử dấu chấm (.) Và dấu ngoặc ([và]).

Ví dụ sau minh họa việc tạo mảng:

//using semicolon separator
let array1 = [| 1; 2; 3; 4; 5; 6 |]
for i in 0 .. array1.Length - 1 do
   printf "%d " array1.[i]
printfn" "

// without semicolon separator
let array2 =
   [|
      1
      2
      3
      4
      5
   |]
for i in 0 .. array2.Length - 1 do
   printf "%d " array2.[i]
printfn" "

//using sequence
let array3 = [| for i in 1 .. 10 -> i * i |]
for i in 0 .. array3.Length - 1 do
   printf "%d " array3.[i]
printfn" "

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

1 2 3 4 5 6
1 2 3 4 5
1 4 9 16 25 36 49 64 81 100

Các thao tác cơ bản trên mảng

Mô-đun thư viện Microsoft.FSharp.Collections.Array hỗ trợ các hoạt động trên mảng một chiều.

Bảng sau đây trình bày các thao tác cơ bản trên Mảng:

Giá trị Sự miêu tả
nối thêm: 'T [] →' T [] → 'T [] Tạo một mảng chứa các phần tử của một mảng theo sau là các phần tử của mảng khác.
trung bình: ^ T [] → ^ T Trả về giá trị trung bình của các phần tử trong một mảng.
AverageBy: ('T → ^ U) →' T [] → ^ U Trả về giá trị trung bình của các phần tử được tạo bằng cách áp dụng một hàm cho từng phần tử của mảng.
blit: 'T [] → int →' T [] → int → int → đơn vị Đọc một loạt các phần tử từ một mảng và ghi chúng vào một mảng khác.
chọn: ('T → U option) →' T [] → 'U [] Áp dụng một hàm được cung cấp cho mỗi phần tử của mảng. Trả về một mảng chứa kết quả x cho mỗi phần tử mà hàm trả về Some (x).
thu thập: ('T →' U []) → T [] → 'U [] Áp dụng hàm được cung cấp cho từng phần tử của mảng, nối kết quả và trả về mảng kết hợp.
concat: seq <'T []> →' T [] Tạo một mảng chứa các phần tử của mỗi chuỗi mảng được cung cấp.
sao chép: 'T →' T [] Tạo một mảng có chứa các phần tử của mảng được cung cấp.
tạo: int → 'T →' T [] Tạo một mảng có tất cả các phần tử ban đầu là giá trị được cung cấp.
trống: 'T [] Trả về một mảng trống của kiểu đã cho.
tồn tại: ('T → bool) →' T [] → bool Kiểm tra xem có phần tử nào của mảng thỏa mãn vị từ được cung cấp hay không.
tồn tại2: ('T1 →' T2 → bool) → 'T1 [] →' T2 [] → bool Kiểm tra xem có cặp phần tử tương ứng nào của hai mảng thỏa mãn điều kiện đã cung cấp hay không.
điền: 'T [] → int → int →' T → đơn vị Điền vào một loạt các phần tử của một mảng với giá trị được cung cấp.
bộ lọc: ('T → bool) →' T [] → 'T [] Trả về một tập hợp chỉ chứa các phần tử của mảng được cung cấp mà điều kiện đã cung cấp trả về true.
find: ('T → bool) →' T [] → 'T Trả về phần tử đầu tiên mà hàm đã cung cấp trả về true. Tăng KeyNotFoundException nếu không có phần tử nào như vậy tồn tại.
findIndex: ('T → bool) →' T [] → int Trả về chỉ số của phần tử đầu tiên trong mảng thỏa mãn điều kiện đã cung cấp. Tăng KeyNotFoundException nếu không có phần tử nào thỏa mãn điều kiện.
gấp: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → 'T [] →' Trạng thái Áp dụng một hàm cho mỗi phần tử của mảng, xâu chuỗi đối số tích lũy thông qua tính toán. Nếu hàm đầu vào là f và các phần tử của mảng là i0 ... iN, hàm này tính f (... (fs i0) ...) iN.
fold2: ('Trạng thái →' T1 → 'T2 →' Trạng thái) → 'Trạng thái →' T1 [] → 'T2 [] →' Trạng thái Áp dụng một hàm cho các cặp phần tử từ hai mảng được cung cấp, từ trái sang phải, xâu chuỗi một đối số tích lũy thông qua tính toán. Hai mảng đầu vào phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
foldBack: ('T →' Trạng thái → 'Trạng thái) →' T [] → 'Trạng thái →' Trạng thái Áp dụng một hàm cho mỗi phần tử của mảng, xâu chuỗi đối số tích lũy thông qua tính toán. Nếu hàm đầu vào là f và các phần tử của mảng là i0 ... iN, hàm này tính f i0 (... (f iN s)).
foldBack2: ('T1 →' T2 → 'Trạng thái →' Trạng thái) → 'T1 [] →' T2 [] → 'Trạng thái →' Trạng thái Áp dụng một hàm cho các cặp phần tử từ hai mảng được cung cấp, từ phải sang trái, xâu chuỗi một đối số tích lũy thông qua tính toán. Hai mảng đầu vào phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
forall: ('T → bool) →' T [] → bool Kiểm tra xem tất cả các phần tử của mảng có thỏa mãn điều kiện đã cung cấp hay không.
forall2: ('T1 →' T2 → bool) → 'T1 [] →' T2 [] → bool Kiểm tra xem tất cả các phần tử tương ứng của hai mảng được cung cấp có thỏa mãn điều kiện được cung cấp hay không.
lấy: 'T [] → int →' T Nhận một phần tử từ một mảng.
init: int → (int → 'T) →' T [] Sử dụng một hàm được cung cấp để tạo một mảng của thứ nguyên được cung cấp.
isEmpty: 'T [] → bool Kiểm tra xem một mảng có bất kỳ phần tử nào không.
iter: ('T → đơn vị) →' T [] → đơn vị Áp dụng hàm được cung cấp cho mỗi phần tử của mảng.
iter2: ('T1 →' T2 → đơn vị) → 'T1 [] →' T2 [] → đơn vị) Áp dụng hàm được cung cấp cho một cặp phần tử từ các chỉ mục phù hợp trong hai mảng. Hai mảng phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
iteri: (int → 'T → đơn vị) →' T [] → đơn vị Áp dụng hàm được cung cấp cho mỗi phần tử của mảng. Số nguyên được truyền vào hàm cho biết chỉ số của phần tử.
iteri2: (int → 'T1 →' T2 → đơn vị) → 'T1 [] →' T2 [] → đơn vị Áp dụng hàm đã cung cấp cho một cặp phần tử từ các chỉ mục phù hợp trong hai mảng, đồng thời truyền chỉ mục của các phần tử. Hai mảng phải có cùng độ dài; nếu không, một ArgumentException được nâng lên.
chiều dài: 'T [] → int Trả về độ dài của một mảng. Thuộc tính Length cũng làm điều tương tự.
bản đồ: ('T →' U) → 'T [] →' U [] Tạo một mảng có các phần tử là kết quả của việc áp dụng hàm được cung cấp cho từng phần tử của một mảng được cung cấp.
map2: ('T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] Tạo một mảng có các phần tử là kết quả của việc áp dụng hàm được cung cấp cho các phần tử tương ứng của hai mảng được cung cấp. Hai mảng đầu vào phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
mapi: (int → 'T →' U) → 'T [] →' U [] Tạo một mảng có các phần tử là kết quả của việc áp dụng hàm được cung cấp cho từng phần tử của một mảng được cung cấp. Một chỉ số nguyên được chuyển đến hàm cho biết chỉ số của phần tử đang được chuyển đổi.
mapi2: (int → 'T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] Tạo một mảng có các phần tử là kết quả của việc áp dụng hàm đã cung cấp cho các phần tử tương ứng của hai tập hợp theo cặp, đồng thời chuyển chỉ mục của các phần tử. Hai mảng đầu vào phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
tối đa: 'T [] →' T Trả về giá trị lớn nhất trong số tất cả các phần tử của một mảng. Các toán tử.max được sử dụng để so sánh các phần tử.
maxBy: ('T →' U) → 'T [] →' T Trả về phần tử lớn nhất trong số tất cả các phần tử của mảng, được so sánh qua Operator.max trên kết quả của hàm.
tối thiểu: ('T [] →' T Trả về phần tử nhỏ nhất trong số tất cả các phần tử của một mảng. Operator.min được sử dụng để so sánh các phần tử.
minBy: ('T →' U) → 'T [] →' T Trả về phần tử nhỏ nhất trong số tất cả các phần tử của một mảng. Operator.min được sử dụng để so sánh các phần tử.
ofList: 'T list →' T [] Tạo một mảng từ danh sách được cung cấp.
ofSeq: seq <'T> →' T [] Tạo một mảng từ đối tượng có thể liệt kê được cung cấp.
phân vùng: ('T → bool) →' T [] → 'T [] *' T [] Tách một mảng thành hai mảng, một mảng chứa các phần tử mà điều kiện đã cung cấp trả về true, và cái kia chứa những thứ mà nó trả về false.
hoán vị: (int → int) → 'T [] →' T [] Hoán vị các phần tử của mảng theo hoán vị đã chỉ định.
pick: ('T →' U option) → 'T [] →' U Áp dụng hàm đã cung cấp cho các phần tử liên tiếp của một mảng được cung cấp, trả về kết quả đầu tiên trong đó hàm trả về Some (x) cho một số x. Nếu hàm không bao giờ trả về Some (x), thì KeyNotFoundException được nâng lên.
giảm: ('T →' T → 'T) →' T [] → 'T Áp dụng một hàm cho mỗi phần tử của mảng, xâu chuỗi đối số tích lũy thông qua tính toán. Nếu hàm đầu vào là f và các phần tử của mảng là i0 ... iN, hàm này tính f (... (f i0 i1) ...) iN. Nếu mảng có kích thước bằng không, ArgumentException sẽ được nâng lên.
ReduceBack: ('T →' T → 'T) →' T [] → 'T Áp dụng một hàm cho mỗi phần tử của mảng, xâu chuỗi đối số tích lũy thông qua tính toán. Nếu hàm đầu vào là f và các phần tử là i0 ... iN, hàm này tính f i0 (... (f iN-1 iN)). Nếu mảng có kích thước bằng không, ArgumentException sẽ được nâng lên.
rev: 'T [] →' T [] Đảo ngược thứ tự của các phần tử trong một mảng được cung cấp.
quét: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → 'T [] →' Trạng thái []) Các hành vi giống như gấp, nhưng trả về kết quả trung gian cùng với kết quả cuối cùng.
scanBack: ('T →' State → 'State) →' T [] → 'State →' State [] Hoạt động giống như foldBack, nhưng trả về kết quả trung gian cùng với kết quả cuối cùng.
đặt: 'T [] → int →' T → đơn vị Đặt một phần tử của một mảng.
sắp xếp: 'T [] →' T [] Sắp xếp các phần tử của một mảng và trả về một mảng mới. Operator.compare được sử dụng để so sánh các phần tử.
sortBy: ('T →' Key) → 'T [] →' T [] Sắp xếp các phần tử của một mảng bằng cách sử dụng hàm được cung cấp để biến đổi các phần tử thành kiểu dựa trên thao tác sắp xếp và trả về một mảng mới. Operator.compare được sử dụng để so sánh các phần tử.
sortInPlace: 'T [] → đơn vị Sắp xếp các phần tử của một mảng bằng cách thay đổi mảng tại chỗ, sử dụng hàm so sánh được cung cấp. Operator.compare được sử dụng để so sánh các phần tử.
sortInPlaceBy: ('T →' Key) → 'T [] → đơn vị Sắp xếp các phần tử của một mảng bằng cách thay đổi mảng tại chỗ, sử dụng phép chiếu được cung cấp cho các phím. Operator.compare được sử dụng để so sánh các phần tử.
sortInPlaceWith: ('T →' T → int) → 'T [] → đơn vị Sắp xếp các phần tử của một mảng bằng cách sử dụng hàm so sánh được cung cấp để thay đổi mảng tại chỗ.
sortVới: ('T →' T → int) → 'T [] →' T [] Sắp xếp các phần tử của một mảng bằng cách sử dụng hàm so sánh được cung cấp và trả về một mảng mới.
sub: 'T [] → int → int →' T [] Tạo một mảng có chứa dải con được cung cấp, được chỉ định bởi chỉ số và độ dài bắt đầu.
tổng: 'T [] → ^ T Trả về tổng các phần tử trong mảng.
sumBy: ('T → ^ U) →' T [] → ^ U Trả về tổng kết quả được tạo bằng cách áp dụng một hàm cho từng phần tử của mảng.
toList: 'T [] →' T list Chuyển đổi mảng được cung cấp thành danh sách.
toSeq: 'T [] → seq <' T> Xem mảng được cung cấp dưới dạng một chuỗi.
tryFind: ('T → bool) →' T [] → 'T tùy chọn Trả về phần tử đầu tiên trong mảng được cung cấp mà hàm đã cung cấp trả về true. Lợi nhuậnNone nếu không có phần tử như vậy tồn tại.
tryFindIndex: ('T → bool) →' T [] → int option Trả về chỉ số của phần tử đầu tiên trong mảng thỏa mãn điều kiện đã cung cấp.
tryPick: ('T →' U option) → 'T [] →' U option Áp dụng hàm đã cung cấp cho các phần tử kế tiếp của mảng được cung cấp và trả về kết quả đầu tiên trong đó hàm trả về Some (x) cho một số x. Nếu hàm không bao giờ trả về Some (x),None Được trả lại.
giải nén: ('T1 *' T2) [] → 'T1 [] *' T2 [] Tách một mảng các cặp tuple thành một bộ gồm hai mảng.
giải nén3: ('T1 *' T2 * 'T3) [] →' T1 [] * 'T2 [] *' T3 [] Tách một mảng gồm ba phần tử thành một bộ ba mảng.
zeroCreate: int → 'T [] Tạo một mảng có các phần tử ban đầu được đặt thành giá trị mặc định Unchecked.defaultof <'T>.
zip: 'T1 [] →' T2 [] → ('T1 *' T2) [] Kết hợp hai mảng thành một mảng bộ giá trị có hai phần tử. Hai mảng phải có độ dài bằng nhau; nếu không, ArgumentException được nâng lên.
zip3: 'T1 [] →' T2 [] → 'T3 [] → (' T1 * 'T2 * 113' T3) [] Kết hợp ba mảng thành một mảng bộ giá trị có ba phần tử. Ba mảng phải có độ dài bằng nhau; nếu không, ArgumentException được nâng lên.

Trong phần sau, chúng ta sẽ xem cách sử dụng của một số chức năng này.

Tạo mảng bằng các hàm

Mô-đun Array cung cấp một số chức năng tạo một mảng từ đầu.

  • Các Array.empty hàm tạo một mảng trống mới.

  • Các Array.create hàm tạo một mảng có kích thước xác định và đặt tất cả các phần tử thành các giá trị đã cho.

  • Các Array.init hàm tạo một mảng, cho trước một thứ nguyên và một hàm tạo các phần tử.

  • Các Array.zeroCreate hàm tạo ra một mảng trong đó tất cả các phần tử được khởi tạo bằng giá trị 0.

  • Các Array.copy hàm tạo một mảng mới chứa các phần tử được sao chép từ một mảng hiện có.

  • Các Array.sub hàm tạo một mảng mới từ một dải con của một mảng.

  • Các Array.append hàm tạo một mảng mới bằng cách kết hợp hai mảng hiện có.

  • Các Array.choose hàm chọn các phần tử của một mảng để đưa vào một mảng mới.

  • Các Array.collect hàm chạy một hàm được chỉ định trên mỗi phần tử mảng của một mảng hiện có và sau đó thu thập các phần tử được tạo bởi hàm và kết hợp chúng thành một mảng mới.

  • Các Array.concat hàm nhận một chuỗi các mảng và kết hợp chúng thành một mảng duy nhất.

  • Các Array.filter hàm nhận một hàm điều kiện Boolean và tạo một mảng mới chỉ chứa các phần tử đó từ mảng đầu vào mà điều kiện là đúng.

  • Các Array.rev hàm tạo một mảng mới bằng cách đảo ngược thứ tự của một mảng hiện có.

Các ví dụ sau đây chứng minh các chức năng này:

ví dụ 1

(* using create and set *)
let array1 = Array.create 10 ""
for i in 0 .. array1.Length - 1 do
   Array.set array1 i (i.ToString())
for i in 0 .. array1.Length - 1 do
   printf "%s " (Array.get array1 i)
printfn " "

(* empty array *)
let array2 = Array.empty
printfn "Length of empty array: %d" array2.Length

let array3 = Array.create 10 7.0
printfn "Float Array: %A" array3

(* using the init and zeroCreate *)
let array4 = Array.init 10 (fun index -> index * index)
printfn "Array of squares: %A" array4

let array5 : float array = Array.zeroCreate 10
let (myZeroArray : float array) = Array.zeroCreate 10
printfn "Float Array: %A" array5

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

0 1 2 3 4 5 6 7 8 9
Length of empty array: 0
Float Array: [|7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0|]
Array of squares: [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81|]
Float Array: [|0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0|]

Ví dụ 2

(* creating subarray from element 5 *)
(* containing 15 elements thereon *)

let array1 = [| 0 .. 50 |]
let array2 = Array.sub array1 5 15
printfn "Sub Array:"
printfn "%A" array2

(* appending two arrays *)
let array3 = [| 1; 2; 3; 4|]
let array4 = [| 5 .. 9 |]
printfn "Appended Array:"
let array5 = Array.append array3 array4
printfn "%A" array5

(* using the Choose function *)
let array6 = [| 1 .. 20 |]
let array7 = Array.choose (fun elem -> if elem % 3 = 0 then
                                             Some(float (elem))
                                          else
                                             None) array6
printfn "Array with Chosen elements:"
printfn "%A" array7

(*using the Collect function *)
let array8 = [| 2 .. 5 |]
let array9 = Array.collect (fun elem -> [| 0 .. elem - 1 |]) array8
printfn "Array with collected elements:"
printfn "%A" array9

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Sub Array:
[|5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19|]
Appended Array:
[|1; 2; 3; 4; 5; 6; 7; 8; 9|]
Array with Chosen elements:
[|3.0; 6.0; 9.0; 12.0; 15.0; 18.0|]
Array with collected elements:
[|0; 1; 0; 1; 2; 0; 1; 2; 3; 0; 1; 2; 3; 4|]

Tìm kiếm Mảng

Các Array.find hàm nhận một hàm Boolean và trả về phần tử đầu tiên mà hàm trả về true, hàm khác trả về một KeyNotFoundException.

Các Array.findIndex hàm hoạt động tương tự ngoại trừ việc nó trả về chỉ mục của phần tử thay vì chính phần tử đó.

Ví dụ sau đây chứng minh điều này.

Microsoft cung cấp ví dụ chương trình thú vị này, tìm phần tử đầu tiên trong phạm vi của một số nhất định vừa là một hình vuông hoàn hảo vừa là một hình lập phương hoàn hảo -

let array1 = [| 2 .. 100 |]
let delta = 1.0e-10
let isPerfectSquare (x:int) =
   let y = sqrt (float x)
   abs(y - round y) < delta

let isPerfectCube (x:int) =
   let y = System.Math.Pow(float x, 1.0/3.0)
   abs(y - round y) < delta

let element = Array.find (fun elem -> isPerfectSquare elem && isPerfectCube elem) array1

let index = Array.findIndex (fun elem -> isPerfectSquare elem && isPerfectCube elem) array1

printfn "The first element that is both a square and a cube is %d and its index is %d." element index

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The first element that is both a square and a cube is 64 and its index is 62.

Các List<'T> lớp đại diện cho một danh sách các đối tượng được đánh máy mạnh có thể được truy cập bằng chỉ mục.

Nó là một đối tác có thể thay đổi của lớp Danh sách. Nó tương tự như mảng, vì nó có thể được truy cập bởi một chỉ mục, tuy nhiên, không giống như mảng, danh sách có thể được thay đổi kích thước. Do đó bạn không cần chỉ định kích thước trong khi khai báo.

Tạo danh sách có thể thay đổi

Danh sách được tạo bằng cách sử dụng newtừ khóa và gọi hàm tạo của danh sách. Ví dụ sau đây chứng minh điều này -

(* Creating a List *)
open System.Collections.Generic

let booksList = new List<string>()
booksList.Add("Gone with the Wind")
booksList.Add("Atlas Shrugged")
booksList.Add("Fountainhead")
booksList.Add("Thornbirds")
booksList.Add("Rebecca")
booksList.Add("Narnia")

booksList |> Seq.iteri (fun index item -> printfn "%i: %s" index booksList.[index])

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

0: Gone with the Wind
1: Atlas Shrugged
2: Fountainhead
3: Thornbirds
4: Rebecca
5: Narnia

Danh sách (T) Class

Lớp List (T) đại diện cho một danh sách các đối tượng được đánh máy mạnh có thể được truy cập bằng chỉ mục. Nó cung cấp các phương pháp tìm kiếm, sắp xếp và thao tác với danh sách.

Các bảng sau cung cấp các thuộc tính, hàm tạo và các phương thức của lớp Danh sách (T):

Tính chất

Bất động sản Sự miêu tả
Sức chứa Lấy hoặc đặt tổng số phần tử mà cấu trúc dữ liệu bên trong có thể giữ mà không cần thay đổi kích thước.
Đếm Nhận số phần tử có trong Danh sách (T).
Mục Nhận hoặc đặt phần tử ở chỉ mục được chỉ định.

Người xây dựng

Constructor Sự miêu tả
Danh sách (T) () Khởi tạo một phiên bản mới của lớp List (T) trống và có dung lượng ban đầu mặc định.
Danh sách (T) (IEnumerable (T)) Khởi tạo một phiên bản mới của lớp List (T) có chứa các phần tử được sao chép từ tập hợp đã chỉ định và có đủ khả năng để chứa số phần tử được sao chép.
Danh sách (T) (Int32) Khởi tạo một phiên bản mới của lớp List (T) trống và có dung lượng ban đầu được chỉ định.

phương pháp

Phương pháp Sự miêu tả
Thêm vào Thêm một đối tượng vào cuối Danh sách (T).
AddRange Thêm các phần tử của tập hợp đã chỉ định vào cuối Danh sách (T).
AsReadOnly Trả về trình bao bọc IList (T) chỉ đọc cho tập hợp hiện tại.
Tìm kiếm nhị phân (T) Tìm kiếm toàn bộ Danh sách đã sắp xếp (T) cho một phần tử bằng cách sử dụng trình so sánh mặc định và trả về chỉ số dựa trên 0 của phần tử.
Tìm kiếm nhị phân (T, IComparer (T)) Tìm kiếm toàn bộ Danh sách đã sắp xếp (T) cho một phần tử bằng cách sử dụng trình so sánh được chỉ định và trả về chỉ mục dựa trên 0 của phần tử.
Tìm kiếm nhị phân (Int32, Int32, T, IComparer (T)) Tìm kiếm một phạm vi phần tử trong Danh sách đã sắp xếp (T) cho một phần tử bằng cách sử dụng trình so sánh được chỉ định và trả về chỉ số dựa trên 0 của phần tử.
Thông thoáng Loại bỏ tất cả các phần tử khỏi Danh sách (T).
Chứa đựng Xác định xem một phần tử có trong Danh sách (T) hay không.
ConvertAll (TOutput) Chuyển đổi các phần tử trong Danh sách hiện tại (T) thành một kiểu khác và trả về một danh sách chứa các phần tử đã chuyển đổi.
CopyTo (T []) Sao chép toàn bộ Danh sách (T) sang mảng một chiều tương thích, bắt đầu từ đầu mảng đích.
CopyTo (T [], Int32) Sao chép toàn bộ Danh sách (T) vào một mảng một chiều tương thích, bắt đầu từ chỉ mục được chỉ định của mảng đích.
CopyTo (Int32, T [], Int32, Int32) Sao chép một loạt các phần tử từ Danh sách (T) sang một mảng một chiều tương thích, bắt đầu từ chỉ mục được chỉ định của mảng đích.
Bằng (Đối tượng) Xác định xem đối tượng được chỉ định có bằng đối tượng hiện tại hay không. (Được kế thừa từ Object.)
Tồn tại Xác định xem Danh sách (T) có chứa các phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định hay không.
Hoàn thiện Cho phép một đối tượng cố gắng giải phóng tài nguyên và thực hiện các hoạt động dọn dẹp khác trước khi nó được thu hồi bằng cách thu gom rác (Kế thừa từ Đối tượng).
Tìm thấy Tìm kiếm một phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định và trả về lần xuất hiện đầu tiên trong toàn bộ Danh sách (T).
FindAll Truy xuất tất cả các phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định.
FindIndex (Vị từ (T)) Tìm kiếm một phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định và trả về chỉ mục dựa trên 0 của lần xuất hiện đầu tiên trong toàn bộ Danh sách (T).
FindIndex (Int32, Predicate (T)) Tìm kiếm một phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định và trả về chỉ mục dựa trên 0 của lần xuất hiện đầu tiên trong phạm vi các phần tử trong Danh sách (T) kéo dài từ chỉ mục được chỉ định đến phần tử cuối cùng.
FindIndex (Int32, Int32, Predicate (T)) Tìm kiếm một phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định và trả về chỉ số dựa trên 0 của lần xuất hiện đầu tiên trong phạm vi các phần tử trong Danh sách (T) bắt đầu tại chỉ mục được chỉ định và chứa số phần tử được chỉ định.
FindLast Tìm kiếm một phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định và trả về lần xuất hiện cuối cùng trong toàn bộ Danh sách (T).
FindLastIndex (Vị từ (T)) Tìm kiếm một phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định và trả về chỉ mục dựa trên 0 của lần xuất hiện cuối cùng trong toàn bộ Danh sách (T).
FindLastIndex (Int32, Predicate (T)) Tìm kiếm một phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định và trả về chỉ số dựa trên 0 của lần xuất hiện cuối cùng trong phạm vi các phần tử trong Danh sách (T) kéo dài từ phần tử đầu tiên đến chỉ mục được chỉ định.
FindLastIndex (Int32, Int32, Predicate (T)) Tìm kiếm một phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định và trả về chỉ số dựa trên 0 của lần xuất hiện cuối cùng trong phạm vi các phần tử trong Danh sách (T) chứa số phần tử được chỉ định và kết thúc ở chỉ mục đã chỉ định.
Cho mỗi Thực hiện hành động được chỉ định trên từng phần tử của Danh sách (T).
GetEnumerator Trả về một điều tra viên lặp qua Danh sách (T).
GetHashCode Đóng vai trò là hàm băm mặc định. (Được kế thừa từ Object.)
GetRange Tạo một bản sao ngắn của một loạt các phần tử trong Danh sách nguồn (T).
GetType Rút ra loại của trường hợp hiện tại. (Được kế thừa từ Object.)
IndexOf (T) Tìm kiếm đối tượng được chỉ định và trả về chỉ mục dựa trên 0 của lần xuất hiện đầu tiên trong toàn bộ Danh sách (T).
IndexOf (T, Int32) Tìm kiếm đối tượng được chỉ định và trả về chỉ mục dựa trên 0 của lần xuất hiện đầu tiên trong phạm vi các phần tử trong Danh sách (T) kéo dài từ chỉ mục được chỉ định đến phần tử cuối cùng.
IndexOf (T, Int32, Int32) Tìm kiếm đối tượng được chỉ định và trả về chỉ số dựa trên 0 của lần xuất hiện đầu tiên trong phạm vi các phần tử trong Danh sách (T) bắt đầu từ chỉ mục được chỉ định và chứa số phần tử được chỉ định.
Chèn Chèn một phần tử vào Danh sách (T) tại chỉ mục được chỉ định.
InsertRange Chèn các phần tử của một tập hợp vào Danh sách (T) tại chỉ mục được chỉ định.
LastIndexOf (T) Tìm kiếm đối tượng được chỉ định và trả về chỉ mục dựa trên 0 của lần xuất hiện cuối cùng trong toàn bộ Danh sách (T).
LastIndexOf (T, Int32) Tìm kiếm đối tượng được chỉ định và trả về chỉ số dựa trên 0 của lần xuất hiện cuối cùng trong phạm vi các phần tử trong Danh sách (T) kéo dài từ phần tử đầu tiên đến chỉ mục được chỉ định.
LastIndexOf (T, Int32, Int32) Tìm kiếm đối tượng được chỉ định và trả về chỉ số dựa trên 0 của lần xuất hiện cuối cùng trong phạm vi các phần tử trong Danh sách (T) chứa số phần tử được chỉ định và kết thúc ở chỉ mục đã chỉ định.
MemberwiseClone Tạo một bản sao nông của Đối tượng hiện tại. (Được kế thừa từ Object.)
Tẩy Loại bỏ sự xuất hiện đầu tiên của một đối tượng cụ thể khỏi Danh sách (T).
Xóa tất cả Loại bỏ tất cả các phần tử phù hợp với các điều kiện được xác định bởi vị từ được chỉ định.
RemoveAt Loại bỏ phần tử tại chỉ mục được chỉ định của Danh sách (T).
RemoveRange Xóa một loạt các phần tử khỏi Danh sách (T).
Đảo ngược() Đảo ngược thứ tự của các phần tử trong toàn bộ Danh sách (T).
Đảo ngược (Int32, Int32) Đảo ngược thứ tự của các phần tử trong phạm vi được chỉ định.
Sắp xếp () Sắp xếp các phần tử trong toàn bộ Danh sách (T) bằng trình so sánh mặc định.
Sắp xếp (So sánh (T)) Sắp xếp các phần tử trong toàn bộ Danh sách (T) bằng Hệ thống được chỉ định. So sánh (T).
Sắp xếp (IComparer (T)) Sắp xếp các phần tử trong toàn bộ Danh sách (T) bằng trình so sánh được chỉ định.
Sắp xếp (Int32, Int32, IComparer (T)) Sắp xếp các phần tử trong một loạt các phần tử trong Danh sách (T) bằng cách sử dụng trình so sánh được chỉ định.
ToArray Sao chép các phần tử của Danh sách (T) sang một mảng mới.
ToString Trả về một chuỗi đại diện cho các đối tượng hiện tại. (Được kế thừa từ Object.)
TrimExcess Đặt dung lượng thành số phần tử thực tế trong Danh sách (T), nếu số đó nhỏ hơn giá trị ngưỡng.
TrueForAll Xác định xem mọi phần tử trong Danh sách (T) có khớp với các điều kiện được xác định bởi vị từ được chỉ định hay không.

Thí dụ

(* Creating a List *)
open System.Collections.Generic

let booksList = new List<string>()
booksList.Add("Gone with the Wind")
booksList.Add("Atlas Shrugged")
booksList.Add("Fountainhead")
booksList.Add("Thornbirds")
booksList.Add("Rebecca")
booksList.Add("Narnia")

printfn"Total %d books" booksList.Count
booksList |> Seq.iteri (fun index item -> printfn "%i: %s" index booksList.[index])
booksList.Insert(2, "Roots")

printfn("after inserting at index 2")
printfn"Total %d books" booksList.Count

booksList |> Seq.iteri (fun index item -> printfn "%i: %s" index booksList.[index])
booksList.RemoveAt(3)

printfn("after removing from index 3")
printfn"Total %d books" booksList.Count

booksList |> Seq.iteri (fun index item -> printfn "%i: %s" index booksList.[index])

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Total 6 books
0: Gone with the Wind
1: Atlas Shrugged
2: Fountainhead
3: Thornbirds
4: Rebecca
5: Narnia
after inserting at index 2
Total 7 books
0: Gone with the Wind
1: Atlas Shrugged
2: Roots
3: Fountainhead
4: Thornbirds
5: Rebecca
6: Narnia
after removing from index 3
Total 6 books
0: Gone with the Wind
1: Atlas Shrugged
2: Roots
3: Thornbirds
4: Rebecca
5: Narnia

Các Dictionary<'TKey, 'TValue> lớp là tương tự có thể thay đổi của cấu trúc dữ liệu bản đồ F # và chứa nhiều chức năng giống nhau.

Tóm tắt lại từ chương Bản đồ trong F #, bản đồ là một loại tập hợp đặc biệt liên kết các giá trị với khóa.

Tạo từ điển có thể thay đổi

Từ điển có thể thay đổi được tạo bằng cách sử dụng newtừ khóa và gọi hàm tạo của danh sách. Ví dụ sau đây chứng minh điều này -

open System.Collections.Generic
let dict = new Dictionary<string, string>()
dict.Add("1501", "Zara Ali")
dict.Add("1502","Rishita Gupta")
dict.Add("1503","Robin Sahoo")
dict.Add("1504","Gillian Megan")
printfn "Dictionary - students: %A" dict

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Dictionary - students: seq
[[1501, Zara Ali]; [1502, Rishita Gupta]; [1503, Robin Sahoo];
[1504, Gillian Megan]]

Lớp Từ điển (TKey, TValue)

Lớp Từ điển (TKey, TValue) đại diện cho một tập hợp các khóa và giá trị.

Các bảng sau cung cấp các thuộc tính, hàm tạo và các phương thức của lớp Danh sách (T):

Tính chất

Bất động sản Sự miêu tả
Người so sánh Nhận IEqualityComparer (T) được sử dụng để xác định mức độ bình đẳng của các khóa cho từ điển.
Đếm Nhận số lượng cặp khóa / giá trị có trong Từ điển (TKey, TValue).
Mục Nhận hoặc đặt giá trị được liên kết với khóa được chỉ định.
Chìa khóa Nhận bộ sưu tập có chứa các khóa trong Từ điển (TKey, TValue).
Giá trị Nhận một tập hợp chứa các giá trị trong Từ điển (TKey, TValue).

Người xây dựng

Người xây dựng Sự miêu tả
Từ điển (TKey, TValue) () Khởi tạo một phiên bản mới của Dictionary(TKey, TValue) lớp trống, có dung lượng ban đầu mặc định và sử dụng trình so sánh bình đẳng mặc định cho loại khóa.
Từ điển (TKey, TValue) (IDictionary (TKey, TValue)) Khởi tạo một phiên bản mới của Dictionary(TKey, TValue) lớp có chứa các phần tử được sao chép từ IDictionary(TKey, TValue) và sử dụng trình so sánh bình đẳng mặc định cho loại khóa.
Từ điển (TKey, TValue) (IEqualityComparer (TKey)) Khởi tạo một phiên bản mới của Dictionary(TKey, TValue) lớp trống, có dung lượng ban đầu mặc định và sử dụng IEqualityComparer(T).
Từ điển (TKey, TValue) (Int32) Khởi tạo một phiên bản mới của Dictionary(TKey, TValue) lớp trống, có dung lượng ban đầu được chỉ định và sử dụng trình so sánh bình đẳng mặc định cho loại khóa.
Từ điển (TKey, TValue) (IDictionary (TKey, TValue), IEqualityComparer (TKey)) Khởi tạo một phiên bản mới của Dictionary(TKey, TValue) lớp có chứa các phần tử được sao chép từ IDictionary(TKey, TValue) và sử dụng IEqualityComparer(T).
Từ điển (TKey, TValue) (Int32, IEqualityComparer (TKey)) Khởi tạo một phiên bản mới của Dictionary(TKey, TValue) lớp trống, có dung lượng ban đầu được chỉ định và sử dụng IEqualityComparer(T).
Từ điển (TKey, TValue) (SerializationInfo, StreamingContext) Khởi tạo một phiên bản mới của ictionary(TKey, TValue) lớp với dữ liệu được tuần tự hóa.

Phương pháp

phương pháp Sự miêu tả
Thêm vào Thêm khóa và giá trị đã chỉ định vào từ điển.
Thông thoáng Xóa tất cả các khóa và giá trị khỏi Từ điển (TKey, TValue).
ContainsKey Xác định xem Từ điển (TKey, TValue) có chứa khóa được chỉ định hay không.
ContainsValue Xác định xem Từ điển (TKey, TValue) có chứa một giá trị cụ thể hay không.
Bằng (Đối tượng) Xác định xem đối tượng được chỉ định có bằng đối tượng hiện tại hay không. (Được kế thừa từ Object.)
Hoàn thiện Cho phép một đối tượng cố gắng giải phóng tài nguyên và thực hiện các hoạt động dọn dẹp khác trước khi nó được thu hồi bằng cách thu gom rác. (Được kế thừa từ Object.)
GetEnumerator Trả về một điều tra viên đã lặp qua Từ điển (TKey, TValue).
GetHashCode Đóng vai trò là hàm băm mặc định. (Được kế thừa từ Object.)
GetObjectData Triển khai giao diện System.Runtime.Serialization.ISerializable và trả về dữ liệu cần thiết để tuần tự hóa phiên bản Dictionary (TKey, TValue).
GetType Rút ra loại của trường hợp hiện tại. (Được kế thừa từ Object.)
MemberwiseClone Tạo một bản sao nông của Đối tượng hiện tại. (Được kế thừa từ Object.)
OnDeserialization Triển khai giao diện System.Runtime.Serialization.ISerializable và tăng sự kiện deserialization khi quá trình deserialization hoàn tất.
Tẩy Xóa giá trị bằng khóa được chỉ định khỏi Từ điển (TKey, TValue).
ToString Trả về một chuỗi đại diện cho các đối tượng hiện tại. (Được kế thừa từ Object.)
TryGetValue Nhận giá trị được liên kết với khóa được chỉ định.

Thí dụ

open System.Collections.Generic
let dict = new Dictionary<string, string>()

dict.Add("1501", "Zara Ali")
dict.Add("1502","Rishita Gupta")
dict.Add("1503","Robin Sahoo")
dict.Add("1504","Gillian Megan")

printfn "Dictionary - students: %A" dict
printfn "Total Number of Students: %d" dict.Count
printfn "The keys: %A" dict.Keys
printf"The Values: %A" dict.Values

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Dictionary - students: seq
[[1501, Zara Ali]; [1502, Rishita Gupta]; [1503, Robin Sahoo];
[1504, Gillian Megan]]
Total Number of Students: 4
The keys: seq ["1501"; "1502"; "1503"; "1504"]
The Values: seq ["Zara Ali"; "Rishita Gupta"; "Robin Sahoo"; "Gillian Megan"]

Đầu vào cơ bản Đầu ra bao gồm -

  • Đọc và ghi vào bảng điều khiển.
  • Đọc từ và ghi vào tệp.

Mô-đun Core.Printf

Chúng tôi đã sử dụng các hàm printfprintfn để ghi vào bảng điều khiển. Trong phần này, chúng ta sẽ xem xét các chi tiết củaPrintf mô-đun của F #.

Ngoài các chức năng trên, mô-đun Core.Printf của F # có nhiều phương pháp khác để in và định dạng bằng cách sử dụng dấu% làm trình giữ chỗ. Bảng sau đây cho thấy các phương pháp với mô tả ngắn gọn:

Giá trị Sự miêu tả
bprintf: StringBuilder → BuilderFormat <'T> →' T In vào StringBuilder.
eprintf: TextWriterFormat <'T> →' T In đầu ra được định dạng sang stderr.
eprintfn: TextWriterFormat <'T> →' T In đầu ra có định dạng sang stderr, thêm một dòng mới.
failwithf: StringFormat <'T,' Kết quả> → 'T In vào bộ đệm chuỗi và đặt ra một ngoại lệ với kết quả đã cho.
fprintf: TextWriter → TextWriterFormat <'T> →' T In cho người viết văn bản.
fprintfn: TextWriter → TextWriterFormat <'T> →' T In cho người viết văn bản, thêm một dòng mới.
kbprintf: (đơn vị → 'Kết quả) → StringBuilder → BuilderFormat <' T, 'Kết quả> →' T Giống như bprintf, nhưng gọi hàm được chỉ định để tạo ra kết quả.
kfprintf: (đơn vị → 'Kết quả) → TextWriter → TextWriterFormat <' T, 'Kết quả> →' T Giống như fprintf, nhưng gọi hàm được chỉ định để tạo ra kết quả.
kprintf: (string → 'Kết quả) → StringFormat <' T, 'Kết quả> →' T Giống như printf, nhưng gọi hàm được chỉ định để tạo ra kết quả. Ví dụ, chúng cho phép lực in xả ra sau khi tất cả đầu ra đã được nhập vào kênh, nhưng không phải trước đó.
ksprintf: (string → 'Kết quả) → StringFormat <' T, 'Kết quả> →' T Giống như sprintf, nhưng gọi hàm được chỉ định để tạo ra kết quả.
printf: TextWriterFormat <'T> →' T In đầu ra được định dạng sang stdout.
printfn: TextWriterFormat <'T> →' T In đầu ra được định dạng sang stdout, thêm một dòng mới.
sprintf: StringFormat <'T> →' T In ra một chuỗi bằng cách sử dụng bộ đệm chuỗi bên trong và trả về kết quả dưới dạng một chuỗi.

Thông số định dạng

Các đặc tả định dạng được sử dụng để định dạng đầu vào hoặc đầu ra, theo nhu cầu của người lập trình.

Đây là các chuỗi có dấu% cho biết phần giữ chỗ định dạng.

Cú pháp của trình giữ chỗ Định dạng là -

%[flags][width][.precision][type]

Các type được hiểu là -

Kiểu Sự miêu tả
% b Định dạng a bool, được định dạng là true hoặc là false.
% c Định dạng một ký tự.
%S Định dạng a string, được định dạng như nội dung của nó, mà không giải thích bất kỳ ký tự thoát nào.
% d,% i Định dạng bất kỳ kiểu số nguyên cơ bản nào được định dạng dưới dạng số nguyên thập phân, được ký nếu kiểu số nguyên cơ bản được ký.
% u Định dạng bất kỳ kiểu số nguyên cơ bản nào được định dạng dưới dạng số nguyên thập phân không dấu.
% x Định dạng bất kỳ kiểu số nguyên cơ bản nào được định dạng dưới dạng số nguyên thập lục phân không dấu, sử dụng các chữ cái thường từ a đến f.
% X Định dạng bất kỳ kiểu số nguyên cơ bản nào được định dạng dưới dạng số nguyên thập lục phân không dấu, sử dụng các chữ cái viết hoa từ A đến F.
% o Định dạng bất kỳ kiểu số nguyên cơ bản nào được định dạng dưới dạng số nguyên bát phân không dấu.
% e,% E,% f,% F,% g,% G Định dạng bất kỳ loại dấu phẩy động cơ bản nào (float, float32) được định dạng bằng cách sử dụng đặc điểm định dạng dấu chấm động kiểu C.
% e,% E Định dạng giá trị có dấu có dạng [-] d.dddde [sign] ddd trong đó d là một chữ số thập phân duy nhất, dddd là một hoặc nhiều chữ số thập phân, ddd là chính xác ba chữ số thập phân và dấu là + hoặc -.
% f Định dạng một giá trị có dấu có dạng [-] dddd.dddd, trong đó dddd là một hoặc nhiều chữ số thập phân. Số chữ số trước dấu thập phân phụ thuộc vào độ lớn của số và số chữ số sau dấu thập phân phụ thuộc vào độ chính xác được yêu cầu.
% g,% G Định dạng giá trị có dấu được in ở định dạng f hoặc e, tùy theo định dạng nào nhỏ gọn hơn đối với giá trị và độ chính xác đã cho.
% M Định dạng giá trị Thập phân.
% O Định dạng bất kỳ giá trị nào, được in bằng cách đóng hộp đối tượng và sử dụng ToString phương pháp.
% A,% + A Định dạng bất kỳ giá trị nào, được in bằng cài đặt bố cục mặc định. Sử dụng% + A để in cấu trúc của các công đoàn bị phân biệt đối xử với các đại diện nội bộ và tư nhân.
% a

Một chỉ định định dạng chung, yêu cầu hai đối số. Đối số đầu tiên là một hàm chấp nhận hai đối số: thứ nhất, tham số ngữ cảnh của loại thích hợp cho hàm định dạng đã cho (ví dụ: TextWriter) và thứ hai, một giá trị để in và xuất hoặc trả về văn bản thích hợp.

Đối số thứ hai là giá trị cụ thể để in.

% t Công cụ chỉ định định dạng chung, yêu cầu một đối số: một hàm chấp nhận tham số ngữ cảnh thuộc loại thích hợp cho hàm định dạng đã cho (aTextWriter) và xuất hoặc trả về văn bản thích hợp. Các kiểu số nguyên cơ bản làbyte, sbyte, int16, uint16, int32, uint32, int64, uint64, nativeint,unativeint. Các loại dấu phẩy động cơ bản là floatfloat32.

Các widthlà một tham số tùy chọn. Nó là một số nguyên cho biết độ rộng nhỏ nhất của kết quả. Ví dụ:% 5d in ra một số nguyên có ít nhất khoảng trắng là 5 ký tự.

Có hiệu lực flags được mô tả trong bảng sau:

Giá trị Sự miêu tả
0 Chỉ định thêm số không thay vì khoảng trắng để tạo nên chiều rộng cần thiết.
- Chỉ định căn trái kết quả trong chiều rộng được chỉ định.
+ Chỉ định thêm ký tự + nếu số là số dương (để khớp với dấu - đối với số âm).
' ' (không gian) Chỉ định thêm khoảng trắng nếu số là số dương (để khớp với dấu - cho số âm).
# Không hợp lệ.

Thí dụ

printf "Hello "
printf "World"
printfn ""
printfn "Hello "
printfn "World"
printf "Hi, I'm %s and I'm a %s" "Rohit" "Medical Student"

printfn "d: %f" 212.098f
printfn "e: %f" 504.768f

printfn "x: %g" 212.098f
printfn "y: %g" 504.768f

printfn "x: %e" 212.098f
printfn "y: %e" 504.768f
printfn "True: %b" true

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Hello World
Hello
World
Hi, I'm Rohit and I'm a Medical Studentd: 212.098000
e: 504.768000
x: 212.098
y: 504.768
x: 2.120980e+002
y: 5.047680e+002
True: true

Lớp điều khiển

Lớp này là một phần của .NET framework. Nó đại diện cho các luồng đầu vào, đầu ra và lỗi tiêu chuẩn cho các ứng dụng bảng điều khiển.

Nó cung cấp nhiều phương pháp khác nhau để đọc và ghi vào bảng điều khiển. Bảng sau đây cho thấy các phương pháp:

phương pháp Sự miêu tả
Tiếng kêu bíp() Phát âm thanh bíp qua loa của bảng điều khiển.
Tiếng bíp (Int32, Int32) Phát âm thanh bíp có tần số và thời lượng xác định qua loa của bảng điều khiển.
Thông thoáng Xóa bộ đệm bảng điều khiển và cửa sổ thông tin hiển thị bảng điều khiển tương ứng.
MoveBufferArea (Int32, Int32, Int32, Int32, Int32, Int32) Sao chép một vùng nguồn cụ thể của bộ đệm màn hình vào một vùng đích cụ thể.
MoveBufferArea (Int32, Int32, Int32, Int32, Int32, Int32, Char, ConsoleColor, ConsoleColor) Sao chép một vùng nguồn cụ thể của bộ đệm màn hình vào một vùng đích cụ thể.
OpenStandardError () Nhận dòng lỗi tiêu chuẩn.
OpenStandardError (Int32) Nhận luồng lỗi tiêu chuẩn, được đặt thành kích thước bộ đệm được chỉ định.
OpenStandardInput () Nhận dòng đầu vào tiêu chuẩn.
OpenStandardInput (Int32) Nhận luồng đầu vào tiêu chuẩn, được đặt thành kích thước bộ đệm được chỉ định.
OpenStandardOutput () Nhận dòng đầu ra tiêu chuẩn.
OpenStandardOutput (Int32) Nhận luồng đầu ra tiêu chuẩn, được đặt thành kích thước bộ đệm được chỉ định.
Đọc Đọc ký tự tiếp theo từ luồng đầu vào chuẩn.
Đọc khóa() Lấy ký tự tiếp theo hoặc phím chức năng do người dùng nhấn. Phím đã nhấn được hiển thị trong cửa sổ giao diện điều khiển.
ReadKey (Boolean) Lấy ký tự tiếp theo hoặc phím chức năng do người dùng nhấn. Phím đã nhấn được hiển thị tùy chọn trong cửa sổ giao diện điều khiển.
ReadLine Đọc dòng ký tự tiếp theo từ luồng đầu vào chuẩn.
ResetColor Đặt màu của bảng điều khiển nền trước và nền thành màu mặc định của chúng.
SetBufferSize Đặt chiều cao và chiều rộng của vùng đệm màn hình thành các giá trị được chỉ định.
SetCursorPosition Đặt vị trí của con trỏ.
SetError Đặt thuộc tính Lỗi cho đối tượng TextWriter được chỉ định .
SetIn Đặt thuộc tính In thành đối tượng TextReader được chỉ định .
Đặt ra Đặt thuộc tính Out thành đối tượng TextWriter được chỉ định .
SetWindowPosition Đặt vị trí của cửa sổ bảng điều khiển so với bộ đệm màn hình.
SetWindowSize Đặt chiều cao và chiều rộng của cửa sổ bảng điều khiển thành các giá trị được chỉ định.
Viết (Boolean) Viết biểu diễn văn bản của giá trị Boolean được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (Char) Ghi giá trị ký tự Unicode được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (Char []) Ghi mảng ký tự Unicode được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (thập phân) Ghi biểu diễn văn bản của giá trị Thập phân được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (Double) Viết biểu diễn văn bản của giá trị dấu phẩy động có độ chính xác kép được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (Int32) Viết biểu diễn văn bản của giá trị số nguyên có dấu 32 bit được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (Int64) Viết biểu diễn văn bản của giá trị số nguyên có dấu 64-bit được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (Đối tượng) Ghi biểu diễn văn bản của đối tượng được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (Đơn) Viết biểu diễn văn bản của giá trị dấu phẩy động chính xác đơn được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (Chuỗi) Ghi giá trị chuỗi được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (UInt32) Viết biểu diễn văn bản của giá trị số nguyên không dấu 32 bit được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (UInt64) Viết biểu diễn văn bản của giá trị số nguyên 64-bit không dấu được chỉ định vào luồng đầu ra tiêu chuẩn.
Viết (Chuỗi, Đối tượng) Ghi biểu diễn văn bản của đối tượng được chỉ định vào luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.
Viết (Chuỗi, Đối tượng []) Ghi biểu diễn văn bản của mảng đối tượng được chỉ định vào luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.
Viết (Char [], Int32, Int32) Ghi mảng con được chỉ định của các ký tự Unicode vào luồng đầu ra tiêu chuẩn.
Viết (Chuỗi, Đối tượng, Đối tượng) Ghi biểu diễn văn bản của các đối tượng được chỉ định vào luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.
Viết (Chuỗi, Đối tượng, Đối tượng, Đối tượng) Ghi biểu diễn văn bản của các đối tượng được chỉ định vào luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.
Viết (Chuỗi, Đối tượng, Đối tượng, Đối tượng, Đối tượng) Ghi biểu diễn văn bản của các đối tượng được chỉ định và danh sách tham số có độ dài thay đổi vào luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.
WriteLine () Ghi dòng kết thúc dòng hiện tại vào dòng đầu ra tiêu chuẩn.
WriteLine (Boolean) Viết biểu diễn văn bản của giá trị Boolean được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào dòng đầu ra tiêu chuẩn.
WriteLine (Biểu đồ) Viết ký tự Unicode được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, giá trị cho dòng đầu ra tiêu chuẩn.
WriteLine (Char []) Ghi mảng ký tự Unicode đã chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào luồng đầu ra tiêu chuẩn.
WriteLine (Thập phân) Viết biểu diễn văn bản của giá trị Thập phân được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào luồng đầu ra chuẩn.
WriteLine (Đôi) Viết biểu diễn văn bản của giá trị dấu phẩy động có độ chính xác kép được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào luồng đầu ra tiêu chuẩn.
WriteLine (Int32) Viết biểu diễn văn bản của giá trị số nguyên có dấu 32-bit được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào dòng đầu ra tiêu chuẩn.
WriteLine (Int64) Viết biểu diễn văn bản của giá trị số nguyên có dấu 64-bit được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào dòng đầu ra tiêu chuẩn.
WriteLine (Đối tượng) Viết biểu diễn văn bản của đối tượng được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào dòng đầu ra tiêu chuẩn.
WriteLine (Đơn) Viết biểu diễn văn bản của giá trị dấu phẩy động chính xác đơn được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào dòng đầu ra tiêu chuẩn.
WriteLine (Chuỗi) Ghi giá trị chuỗi đã chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào luồng đầu ra chuẩn.
WriteLine (UInt32) Viết biểu diễn văn bản của giá trị số nguyên không dấu 32 bit được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào dòng đầu ra tiêu chuẩn.
WriteLine (UInt64) Viết biểu diễn văn bản của giá trị số nguyên không dấu 64-bit được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào dòng đầu ra tiêu chuẩn.
WriteLine (Chuỗi, Đối tượng) Viết biểu diễn văn bản của đối tượng được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, tới luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.
WriteLine (Chuỗi, Đối tượng []) Viết biểu diễn văn bản của mảng đối tượng được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, vào luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.
WriteLine (Char [], Int32, Int32) Ghi mảng con được chỉ định của các ký tự Unicode, theo sau là dấu chấm cuối dòng hiện tại, vào dòng đầu ra tiêu chuẩn.
WriteLine (Chuỗi, Đối tượng, Đối tượng) Viết biểu diễn văn bản của các đối tượng được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, đến luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.
WriteLine (Chuỗi, Đối tượng, Đối tượng, Đối tượng) Viết biểu diễn văn bản của các đối tượng được chỉ định, theo sau là dấu chấm cuối dòng hiện tại, đến luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.
WriteLine (Chuỗi, Đối tượng, Đối tượng, Đối tượng, Đối tượng) Viết biểu diễn văn bản của các đối tượng được chỉ định và danh sách tham số có độ dài thay đổi, theo sau là dấu chấm cuối dòng hiện tại, vào luồng đầu ra tiêu chuẩn bằng cách sử dụng thông tin định dạng được chỉ định.

Ví dụ sau minh họa việc đọc từ bảng điều khiển và ghi vào đó:

Thí dụ

open System
let main() =
   Console.Write("What's your name? ")
   let name = Console.ReadLine()
   Console.Write("Hello, {0}\n", name)
   Console.WriteLine(System.String.Format("Big Greetings from {0} and {1}", "TutorialsPoint", "Absoulte Classes"))
   Console.WriteLine(System.String.Format("|{0:yyyy-MMM-dd}|", System.DateTime.Now))
main()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

What's your name? Kabir
Hello, Kabir
Big Greetings from TutorialsPoint and Absoulte Classes
|2015-Jan-05|

Không gian tên System.IO

Không gian tên System.IO chứa nhiều lớp hữu ích để thực hiện I / O cơ bản.

Nó chứa các loại hoặc lớp cho phép đọc và ghi vào tệp và luồng dữ liệu và các loại cung cấp hỗ trợ tệp và thư mục cơ bản.

Các lớp hữu ích để làm việc với hệ thống tệp -

  • Lớp System.IO.File được sử dụng để tạo, thêm và xóa tệp.
  • Lớp System.IO.Directory được sử dụng để tạo, di chuyển và xóa các thư mục.
  • Lớp System.IO.Path thực hiện các hoạt động trên chuỗi, đại diện cho các đường dẫn tệp.
  • Lớp System.IO.FileSystemWatcher cho phép người dùng lắng nghe một thư mục để biết các thay đổi.

Các lớp hữu ích để làm việc với các luồng (chuỗi byte) -

  • Lớp System.IO.StreamReader được sử dụng để đọc các ký tự từ một luồng.
  • Lớp System.IO.StreamWriter được sử dụng để ghi các ký tự vào một luồng.
  • Lớp System.IO.MemoryStream tạo một dòng byte trong bộ nhớ.

Bảng sau đây hiển thị tất cả các lớp được cung cấp trong không gian tên cùng với mô tả ngắn gọn:

Lớp học Sự miêu tả
BinaryReader Đọc các kiểu dữ liệu nguyên thủy dưới dạng giá trị nhị phân trong một bảng mã cụ thể.
BinaryWriter Ghi các kiểu nguyên thủy ở dạng nhị phân vào một luồng và hỗ trợ viết các chuỗi trong một bảng mã cụ thể.
BufferedStream Thêm một lớp đệm để đọc và ghi các hoạt động trên một luồng khác.
Danh mục Hiển thị các phương thức tĩnh để tạo, di chuyển và liệt kê thông qua các thư mục và thư mục con.
DirectoryInfo Hiển thị các phương thức thể hiện để tạo, di chuyển và liệt kê thông qua các thư mục và thư mục con.
DirectoryNotFoundException Ngoại lệ được ném ra khi không thể tìm thấy một phần của tệp hoặc thư mục.
DriveInfo Cung cấp quyền truy cập vào thông tin trên ổ đĩa.
DriveNotFoundException Ngoại lệ được đưa ra khi cố gắng truy cập vào một ổ đĩa hoặc chia sẻ không khả dụng.
EndOfStreamException Ngoại lệ được ném ra khi cố gắng đọc ở cuối luồng.
ErrorEventArgs Cung cấp dữ liệu cho sự kiện FileSystemWatcher.Error.
Tập tin Cung cấp các phương thức tĩnh để tạo, sao chép, xóa, di chuyển và mở một tệp duy nhất và hỗ trợ tạo các đối tượng FileStream.
FileFormatException Ngoại lệ được đưa ra khi một tệp đầu vào hoặc một luồng dữ liệu được cho là tuân theo một đặc điểm định dạng tệp nhất định bị sai định dạng.
Nộp thông tin Cung cấp các thuộc tính và phương thức phiên bản để tạo, sao chép, xóa, di chuyển và mở tệp cũng như hỗ trợ việc tạo các đối tượng FileStream.
FileLoadException Ngoại lệ được ném ra khi tìm thấy một assembly được quản lý nhưng không thể tải được.
FileNotFoundException Ngoại lệ được ném ra khi cố gắng truy cập tệp không tồn tại trên đĩa không thành công.
Tập hồ sơ Hiển thị Luồng xung quanh tệp, hỗ trợ cả hoạt động đọc và ghi đồng bộ và không đồng bộ.
FileSystemEventArgs Cung cấp dữ liệu cho các sự kiện thư mục - Đã thay đổi, Tạo, Đã xóa.
FileSystemInfo Cung cấp lớp cơ sở cho cả hai đối tượng FileInfo và DirectoryInfo.
FileSystemWatcher Lắng nghe các thông báo thay đổi của hệ thống tệp và tăng các sự kiện khi một thư mục hoặc tệp trong thư mục thay đổi.
InternalBufferOverflowException Ngoại lệ được ném ra khi bộ đệm bên trong bị tràn.
Không hợp lệ Ngoại lệ được đưa ra khi luồng dữ liệu có định dạng không hợp lệ.
IODescriptionAttribute Đặt mô tả mà nhà thiết kế trực quan có thể hiển thị khi tham chiếu đến một sự kiện, bộ mở rộng hoặc thuộc tính.
IOException Ngoại lệ được đưa ra khi xảy ra lỗi I / O.
MemoryStream Tạo luồng có kho dự phòng là bộ nhớ.
Con đường Thực hiện các thao tác trên các cá thể Chuỗi có chứa thông tin đường dẫn tệp hoặc thư mục. Các hoạt động này được thực hiện theo cách thức đa nền tảng.
PathTooLongException Ngoại lệ được đưa ra khi đường dẫn hoặc tên tệp dài hơn độ dài tối đa do hệ thống xác định.
PipeException Ném khi xảy ra lỗi trong đường ống đã đặt tên.
Đã đổi tênEventArgs Cung cấp dữ liệu cho sự kiện Đã đổi tên.
Suối Cung cấp một cái nhìn chung về một chuỗi các byte. Đây là một lớp trừu tượng.
StreamReader Triển khai TextReader để đọc các ký tự từ luồng byte trong một mã hóa cụ thể.
StreamWriter Triển khai TextWriter để ghi các ký tự vào một luồng trong một bảng mã cụ thể. Để duyệt mã nguồn .NET Framework cho loại này, hãy xem Nguồn tham chiếu.
StringReader Triển khai một Trình đọc văn bản đọc từ một chuỗi.
StringWriter Triển khai TextWriter để ghi thông tin vào một chuỗi. Thông tin được lưu trữ trong một StringBuilder bên dưới.
TextReader Đại diện cho trình đọc có thể đọc một chuỗi ký tự liên tiếp.
TextWriter Đại diện cho một nhà văn có thể viết một chuỗi ký tự liên tiếp. Lớp này là trừu tượng.
UnmanagedMemoryAccessor Cung cấp quyền truy cập ngẫu nhiên vào các khối bộ nhớ không được quản lý từ mã được quản lý.
UnmanagedMemoryStream Cung cấp quyền truy cập vào các khối bộ nhớ không được quản lý từ mã được quản lý.
WindowsRuntimeStorageExtensions Chứa các phương thức mở rộng cho giao diện IStorageFile và IStorageFolder trong Windows Runtime khi phát triển ứng dụng Windows Store.
WindowsRuntimeStreamExtensions Chứa các phương thức mở rộng để chuyển đổi giữa các luồng trong Windows Runtime và các luồng được quản lý trong ứng dụng .NET for Windows Store.

Thí dụ

Ví dụ sau tạo một tệp có tên là test.txt, viết một thông báo vào đó, đọc văn bản từ tệp và in nó trên bảng điều khiển.

Note - Số lượng mã cần thiết để làm điều này ít hơn một cách đáng ngạc nhiên!

open System.IO // Name spaces can be opened just as modules
File.WriteAllText("test.txt", "Hello There\n Welcome to:\n Tutorials Point")
let msg = File.ReadAllText("test.txt")
printfn "%s" msg

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Hello There
Welcome to:
Tutorials Point

Generics cho phép bạn trì hoãn việc đặc tả kiểu dữ liệu của các phần tử lập trình trong một lớp hoặc một phương thức, cho đến khi nó thực sự được sử dụng trong chương trình. Nói cách khác, generics cho phép bạn viết một lớp hoặc phương thức có thể hoạt động với bất kỳ kiểu dữ liệu nào.

Bạn viết các đặc tả cho lớp hoặc phương thức, với các tham số thay thế cho kiểu dữ liệu. Khi trình biên dịch gặp một phương thức khởi tạo cho lớp hoặc một lệnh gọi hàm cho phương thức, nó sẽ tạo ra mã để xử lý kiểu dữ liệu cụ thể.

Trong F #, các giá trị hàm, phương thức, thuộc tính và các kiểu tổng hợp như lớp, bản ghi và các kết hợp phân biệt có thể là chung.

Các cấu trúc chung chứa ít nhất một tham số kiểu. Các hàm và kiểu chung cho phép bạn viết mã hoạt động với nhiều loại mà không cần lặp lại mã cho từng loại.

Cú pháp

Cú pháp để viết một cấu trúc chung như sau:

// Explicitly generic function.
let function-name<type-parameters> parameter-list =
   function-body

// Explicitly generic method.
[ static ] member object-identifer.method-name<type-parameters> parameter-list [ return-type ] =
   method-body

// Explicitly generic class, record, interface, structure,
// or discriminated union.
type type-name<type-parameters> type-definition

Ví dụ

(* Generic Function *)
let printFunc<'T> x y =
   printfn "%A, %A" x y

printFunc<float> 10.0 20.0

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

10.0, 20.0

Bạn cũng có thể tạo một hàm chung chung bằng cách sử dụng cú pháp dấu ngoặc kép -

(* Generic Function *)
let printFunction (x: 'a) (y: 'a) =
   printfn "%A %A" x y

printFunction 10.0 20.0

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

10.0 20.0

Xin lưu ý rằng khi bạn sử dụng các hàm hoặc phương thức chung, bạn có thể không phải chỉ định các đối số kiểu. Tuy nhiên, trong trường hợp không rõ ràng, bạn có thể cung cấp các đối số kiểu trong dấu ngoặc nhọn như chúng ta đã làm trong ví dụ đầu tiên.

Nếu bạn có nhiều loại, thì bạn phân tách nhiều đối số loại bằng dấu phẩy.

Lớp chung

Giống như các hàm chung, bạn cũng có thể viết các lớp chung. Ví dụ sau đây chứng minh điều này -

type genericClass<'a> (x: 'a) =
   do printfn "%A" x

let gr = new genericClass<string>("zara")
let gs = genericClass( seq { for i in 1 .. 10 -> (i, i*i) } )

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

"zara"
seq [(1, 1); (2, 4); (3, 9); (4, 16); ...]

Một đại biểu là một biến kiểu tham chiếu chứa tham chiếu đến một phương thức. Tham chiếu có thể được thay đổi trong thời gian chạy. Các đại diện F # tương tự như các con trỏ tới các hàm, trong C hoặc C ++.

Tuyên bố đại biểu

Khai báo ủy quyền xác định các phương thức có thể được tham chiếu bởi ủy quyền. Một đại biểu có thể tham chiếu đến một phương thức có cùng chữ ký với của đại biểu.

Cú pháp khai báo ủy quyền là:

type delegate-typename = delegate of type1 -> type2

Ví dụ, hãy xem xét các đại biểu -

// Delegate1 works with tuple arguments.
type Delegate1 = delegate of (int * int) -> int
// Delegate2 works with curried arguments.
type Delegate2 = delegate of int * int -> int

Cả hai đại biểu có thể được sử dụng để tham chiếu bất kỳ phương thức nào có hai tham số int và trả về một biến kiểu int .

Trong cú pháp -

  • type1 đại diện cho (các) loại đối số.

  • type2 đại diện cho kiểu trả về.

Xin lưu ý -

  • Các loại đối số được tự động xử lý.

  • Các đại biểu có thể được đính kèm với các giá trị hàm và các phương thức tĩnh hoặc thể hiện.

  • Các giá trị của hàm F # có thể được truyền trực tiếp dưới dạng đối số để ủy nhiệm các hàm tạo.

  • Đối với một phương thức tĩnh, ủy nhiệm được gọi bằng cách sử dụng tên của lớp và phương thức. Đối với một phương thức thể hiện, tên của thể hiện đối tượng và phương thức được sử dụng.

  • Phương thức Gọi trên kiểu đại biểu gọi hàm được đóng gói.

  • Ngoài ra, các đại biểu có thể được chuyển dưới dạng các giá trị hàm bằng cách tham chiếu đến tên phương thức Gọi mà không có dấu ngoặc đơn.

Ví dụ sau thể hiện khái niệm -

Thí dụ

type Myclass() =
   static member add(a : int, b : int) =
      a + b
   static member sub (a : int) (b : int) =
      a - b
   member x.Add(a : int, b : int) =
      a + b
   member x.Sub(a : int) (b : int) =
      a - b

// Delegate1 works with tuple arguments.
type Delegate1 = delegate of (int * int) -> int
// Delegate2 works with curried arguments.
type Delegate2 = delegate of int * int -> int

let InvokeDelegate1 (dlg : Delegate1) (a : int) (b: int) =
   dlg.Invoke(a, b)
let InvokeDelegate2 (dlg : Delegate2) (a : int) (b: int) =
   dlg.Invoke(a, b)

// For static methods, use the class name, the dot operator, and the
// name of the static method.
let del1 : Delegate1 = new Delegate1( Myclass.add )
let del2 : Delegate2 = new Delegate2( Myclass.sub )

let mc = Myclass()
// For instance methods, use the instance value name, the dot operator, and the instance method name.

let del3 : Delegate1 = new Delegate1( mc.Add )
let del4 : Delegate2 = new Delegate2( mc.Sub )

for (a, b) in [ (400, 200); (100, 45) ] do
   printfn "%d + %d = %d" a b (InvokeDelegate1 del1 a b)
   printfn "%d - %d = %d" a b (InvokeDelegate2 del2 a b)
   printfn "%d + %d = %d" a b (InvokeDelegate1 del3 a b)
   printfn "%d - %d = %d" a b (InvokeDelegate2 del4 a b)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

400 + 200 = 600
400 - 200 = 200
400 + 200 = 600
400 - 200 = 200
100 + 45 = 145
100 - 45 = 55
100 + 45 = 145
100 - 45 = 55

Một kiểu liệt kê là một tập hợp các hằng số nguyên được đặt tên.

Trong F #, enumerations, còn được biết là enums,là các kiểu tích phân trong đó các nhãn được gán cho một tập hợp con các giá trị. Bạn có thể sử dụng chúng thay cho các ký tự để làm cho mã dễ đọc và dễ bảo trì hơn.

Khai báo các bảng kê

Cú pháp chung để khai báo một kiểu liệt kê là:

type enum-name =
   | value1 = integer-literal1
   | value2 = integer-literal2
...

Ví dụ sau minh họa việc sử dụng các phép liệt kê -

Thí dụ

// Declaration of an enumeration.
type Days =
   | Sun = 0
   | Mon = 1
   | Tues = 2
   | Wed = 3
   | Thurs = 4
   | Fri = 5
   | Sat = 6

// Use of an enumeration.
let weekend1 : Days = Days.Sat
let weekend2 : Days = Days.Sun
let weekDay1 : Days = Days.Mon

printfn "Monday: %A" weekDay1
printfn "Saturday: %A" weekend1
printfn "Sunday: %A" weekend2

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Monday: Mon
Saturday: Sat
Sunday: Sun

Đối sánh mẫu cho phép bạn “so sánh dữ liệu với cấu trúc hoặc cấu trúc logic, phân tách dữ liệu thành các phần cấu thành hoặc trích xuất thông tin từ dữ liệu theo nhiều cách khác nhau”.

Nói cách khác, nó cung cấp một cách linh hoạt và mạnh mẽ hơn để kiểm tra dữ liệu dựa trên một loạt các điều kiện và thực hiện một số tính toán dựa trên điều kiện được đáp ứng.

Về mặt khái niệm, nó giống như một chuỗi các câu lệnh if… then.

Cú pháp

Trong các thuật ngữ cấp cao, đối sánh mẫu tuân theo cú pháp này trong F # -

match expr with
| pat1 - result1
| pat2 -> result2
| pat3 when expr2 -> result3
| _ -> defaultResult

Ở đâu,

  • Mỗi | biểu tượng xác định một điều kiện.
  • Biểu tượng -> có nghĩa là "nếu điều kiện là đúng, hãy trả về giá trị này ...".
  • Biểu tượng _ cung cấp mẫu mặc định, có nghĩa là nó khớp với tất cả những thứ khác như ký tự đại diện.

ví dụ 1

Ví dụ sau, tính toán các số Fibonacci bằng cách sử dụng cú pháp đối sánh mẫu -

let rec fib n =
   match n with
   | 0 -> 0
   | 1 -> 1
   | _ -> fib (n - 1) + fib (n - 2)
for i = 1 to 10 do
   printfn "Fibonacci %d: %d" i (fib i)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Fibonacci 1: 1
Fibonacci 2: 1
Fibonacci 3: 2
Fibonacci 4: 3
Fibonacci 5: 5
Fibonacci 6: 8
Fibonacci 7: 13
Fibonacci 8: 21
Fibonacci 9: 34
Fibonacci 10: 55

Bạn cũng có thể xâu chuỗi nhiều điều kiện với nhau để trả về cùng một giá trị. Ví dụ -

Ví dụ 2

let printSeason month =
   match month with
   | "December" | "January" | "February" -> printfn "Winter"
   | "March" | "April" -> printfn "Spring"
   | "May" | "June" -> printfn "Summer"
   | "July" | "August" -> printfn "Rainy"
   | "September" | "October" | "November" -> printfn "Autumn"
   | _ -> printfn "Season depends on month!"

printSeason "February"
printSeason "April"
printSeason "November"
printSeason "July"

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Winter
Spring
Autumn
Rainy

Chức năng đối sánh mẫu

F # cho phép bạn viết các hàm đối sánh mẫu bằng cách sử dụng function từ khóa -

let getRate = function
   | "potato" -> 10.00
   | "brinjal" -> 20.50
   | "cauliflower" -> 21.00
   | "cabbage" -> 8.75
   | "carrot" -> 15.00
   | _ -> nan (* nan is a special value meaning "not a number" *)

printfn "%g"(getRate "potato")
printfn "%g"(getRate "brinjal")
printfn "%g"(getRate "cauliflower")
printfn "%g"(getRate "cabbage")
printfn "%g"(getRate "carrot")

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

10
20.5
21
8.75
15

Thêm bộ lọc hoặc bộ bảo vệ vào mẫu

Bạn có thể thêm bộ lọc hoặc bộ bảo vệ vào các mẫu bằng cách sử dụng when từ khóa.

ví dụ 1

let sign = function
   | 0 -> 0
   | x when x < 0 -> -1
   | x when x > 0 -> 1

printfn "%d" (sign -20)
printfn "%d" (sign 20)
printfn "%d" (sign 0)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

-1
1
0

Ví dụ 2

let compareInt x =
   match x with
   | (var1, var2) when var1 > var2 -> printfn "%d is greater than %d" var1 var2
   | (var1, var2) when var1 < var2 -> printfn "%d is less than %d" var1 var2
   | (var1, var2) -> printfn "%d equals %d" var1 var2

compareInt (11,25)
compareInt (72, 10)
compareInt (0, 0)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

11 is less than 25
72 is greater than 10
0 equals 0

Khớp mẫu với Tuples

Ví dụ sau minh họa cách đối sánh mẫu với các bộ giá trị -

let greeting (name, subject) =
   match (name, subject) with
   | ("Zara", _) -> "Hello, Zara"
   | (name, "English") -> "Hello, " + name + " from the department of English"
   | (name, _) when subject.StartsWith("Comp") -> "Hello, " + name + " from the department of Computer Sc."
   | (_, "Accounts and Finance") -> "Welcome to the department of Accounts and Finance!"
   | _ -> "You are not registered into the system"

printfn "%s" (greeting ("Zara", "English"))
printfn "%s" (greeting ("Raman", "Computer Science"))
printfn "%s" (greeting ("Ravi", "Mathematics"))

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Hello, Zara
Hello, Raman from the department of Computer Sc.
You are not registered into the system

Khớp mẫu với bản ghi

Ví dụ sau minh họa việc đối sánh mẫu với các bản ghi:

type Point = { x: float; y: float }
let evaluatePoint (point: Point) =
   match point with
   | { x = 0.0; y = 0.0 } -> printfn "Point is at the origin."
   | { x = xVal; y = 0.0 } -> printfn "Point is on the x-axis. Value is %f." xVal
   | { x = 0.0; y = yVal } -> printfn "Point is on the y-axis. Value is %f." yVal
   | { x = xVal; y = yVal } -> printfn "Point is at (%f, %f)." xVal yVal

evaluatePoint { x = 0.0; y = 0.0 }
evaluatePoint { x = 10.0; y = 0.0 }
evaluatePoint { x = 0.0; y = 10.0 }
evaluatePoint { x = 10.0; y = 10.0 }

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Point is at the origin.
Point is on the x-axis. Value is 10.000000.
Point is on the y-axis. Value is 10.000000.
Point is at (10.000000, 10.000000).

Một ngoại lệ là một vấn đề phát sinh trong quá trình thực hiện một chương trình. Một ngoại lệ F # là một phản ứng đối với một trường hợp ngoại lệ phát sinh trong khi chương trình đang chạy, chẳng hạn như nỗ lực chia cho không.

Ngoại lệ cung cấp một cách để chuyển quyền kiểm soát từ một phần của chương trình sang phần khác. Xử lý ngoại lệ F # cung cấp các cấu trúc sau:

Xây dựng Sự miêu tả
nâng cao expr Tăng ngoại lệ đã cho.
failwith expr Nâng cao System.Exception ngoại lệ.
thử expr với các quy tắc Bắt các biểu thức phù hợp với các quy tắc mẫu.
thử expr cuối cùng expr Thực hiện finally biểu thức cả khi tính toán thành công và khi một ngoại lệ được đưa ra.
| :? ArgumentException Quy tắc phù hợp với loại ngoại lệ .NET đã cho.
| :? ArgumentException as e Quy tắc phù hợp với loại ngoại lệ .NET đã cho, ràng buộc tên e thành giá trị đối tượng ngoại lệ.
| Thất bại (msg) → expr Quy tắc phù hợp với ngoại lệ F # mang dữ liệu đã cho.
| exn → expr Quy tắc phù hợp với bất kỳ ngoại lệ nào, ràng buộc tên exn thành giá trị đối tượng ngoại lệ.
| exn khi expr → expr Quy tắc phù hợp với ngoại lệ trong điều kiện đã cho, ràng buộc tên exn thành giá trị đối tượng ngoại lệ.

Chúng ta hãy bắt đầu với cú pháp cơ bản của Xử lý ngoại lệ.

Cú pháp

Cú pháp cơ bản cho khối xử lý ngoại lệ F # là:

exception exception-type of argument-type

Ở đâu,

  • exception-type là tên của kiểu ngoại lệ F # mới.

  • argument-type đại diện cho loại đối số có thể được cung cấp khi bạn nêu ra một ngoại lệ của loại này.

  • Nhiều đối số có thể được chỉ định bằng cách sử dụng một loại bộ cho kiểu đối số.

Các try...with biểu thức được sử dụng để xử lý ngoại lệ trong ngôn ngữ F #.

Cú pháp của try… với biểu thức là -

try
   expression1
with
   | pattern1 -> expression2
   | pattern2 -> expression3
...

Các try...finally biểu thức cho phép bạn thực thi mã xóa ngay cả khi một khối mã ném một ngoại lệ.

Cú pháp cho biểu thức try ... cuối cùng là -

try
   expression1
finally
   expression2

Các raisehàm được sử dụng để chỉ ra rằng một lỗi hoặc điều kiện ngoại lệ đã xảy ra. Nó cũng nắm bắt thông tin về lỗi trong một đối tượng ngoại lệ.

Cú pháp cho hàm raise là -

raise (expression)

Các failwith hàm tạo ra một ngoại lệ F #.

Cú pháp cho hàm failwith là:

failwith error-message-string

Các invalidArg hàm tạo ra một ngoại lệ đối số.

invalidArg parameter-name error-message-string

Ví dụ về Xử lý Ngoại lệ

ví dụ 1

Chương trình sau đây cho thấy cách xử lý ngoại lệ cơ bản với một thử đơn giản… với khối -

let divisionprog x y =
   try
      Some (x / y)
   with
      | :? System.DivideByZeroException -> printfn "Division by zero!"; None

let result1 = divisionprog 100 0

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Division by zero!

Ví dụ 2

F # cung cấp một exceptionloại để khai báo ngoại lệ. Bạn có thể sử dụng một loại ngoại lệ trực tiếp trong các bộ lọc trongtry...with biểu hiện.

Ví dụ sau đây chứng minh điều này -

exception Error1 of string
// Using a tuple type as the argument type.
exception Error2 of string * int

let myfunction x y =
   try
      if x = y then raise (Error1("Equal Number Error"))
      else raise (Error2("Error Not detected", 100))
   with
      | Error1(str) -> printfn "Error1 %s" str
      | Error2(str, i) -> printfn "Error2 %s %d" str i
myfunction 20 10
myfunction 5 5

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Error2 Error Not detected 100
Error1 Equal Number Error

Ví dụ 3

Ví dụ sau minh họa việc xử lý ngoại lệ lồng nhau:

exception InnerError of string
exception OuterError of string

let func1 x y =
   try
      try
         if x = y then raise (InnerError("inner error"))
         else raise (OuterError("outer error"))
      with
         | InnerError(str) -> printfn "Error:%s" str
   finally
      printfn "From the finally block."

let func2 x y =
   try
      func1 x y
   with
      | OuterError(str) -> printfn "Error: %s" str

func2 100 150
func2 100 100
func2 100 120

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

From the finally block.
Error: outer error
Error:inner error
From the finally block.
From the finally block.
Error: outer error

Ví dụ 4

Hàm sau thể hiện failwith chức năng -

let divisionFunc x y =
   if (y = 0) then failwith "Divisor cannot be zero."
   else
      x / y

let trydivisionFunc x y =
   try
      divisionFunc x y
   with
      | Failure(msg) -> printfn "%s" msg; 0

let result1 = trydivisionFunc 100 0
let result2 = trydivisionFunc 100 4
printfn "%A" result1
printfn "%A" result2

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Divisor cannot be zero.
0
25

Ví dụ 5

Các invalidArghàm tạo ra một ngoại lệ đối số. Chương trình sau đây chứng minh điều này -

let days = [| "Sunday"; "Monday"; "Tuesday"; "Wednesday"; "Thursday"; "Friday"; "Saturday" |]
let findDay day =
   if (day > 7 || day < 1)
      then invalidArg "day" (sprintf "You have entered %d." day)
   days.[day - 1]

printfn "%s" (findDay 1)
printfn "%s" (findDay 5)
printfn "%s" (findDay 9)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Sunday
Thursday
Unhandled Exception:
System.ArgumentException: You have entered 9.
…

Một số thông tin khác về tệp và biến gây ra lỗi trong hệ thống cũng sẽ được hiển thị, tùy thuộc vào hệ thống.

Lớp là kiểu đại diện cho các đối tượng có thể có thuộc tính, phương thức và sự kiện. 'Chúng được sử dụng để mô hình hóa các hành động, quy trình và bất kỳ thực thể khái niệm nào trong ứng dụng'.

Cú pháp

Cú pháp để xác định một loại lớp như sau:

// Class definition:
type [access-modifier] type-name [type-params] [access-modifier] ( parameter-list ) [ as identifier ] =
   [ class ]
      [ inherit base-type-name(base-constructor-args) ]
      [ let-bindings ]
      [ do-bindings ]
      member-list
      ...
   [ end ]

// Mutually recursive class definitions:
type [access-modifier] type-name1 ...
and [access-modifier] type-name2 ...
...

Ở đâu,

  • Các type-namelà bất kỳ số nhận dạng hợp lệ nào. Công cụ sửa đổi quyền truy cập mặc định cho điều này làpublic.

  • Các type-params mô tả các tham số kiểu chung tùy chọn.

  • Các parameter-listmô tả các tham số của hàm tạo. Công cụ sửa đổi quyền truy cập mặc định cho hàm tạo chính làpublic.

  • Các identifier được sử dụng với tùy chọn as từ khóa đặt tên cho biến phiên bản, hoặc self-identifier, có thể được sử dụng trong định nghĩa kiểu để tham chiếu đến thể hiện của kiểu.

  • Các inherit từ khóa cho phép bạn chỉ định lớp cơ sở cho một lớp.

  • Các let các ràng buộc cho phép bạn khai báo các trường hoặc giá trị hàm cục bộ cho lớp.

  • Các do-bindings phần bao gồm mã được thực thi khi xây dựng đối tượng.

  • Các member-list bao gồm các hàm tạo bổ sung, khai báo phương thức thể hiện và tĩnh, khai báo giao diện, ràng buộc trừu tượng, khai báo thuộc tính và sự kiện.

  • Các từ khóa classend đánh dấu bắt đầu và kết thúc của định nghĩa là tùy chọn.

Cấu trúc của một lớp

Hàm tạo là mã tạo ra một thể hiện của kiểu lớp.

Trong F #, các hàm tạo hoạt động hơi khác so với các ngôn ngữ .Net khác. Trong định nghĩa lớp, các đối số của hàm tạo chính được mô tả dưới dạng danh sách tham số.

Phần thân của hàm tạo bao gồm letdo ràng buộc.

Bạn có thể thêm các hàm tạo bổ sung bằng cách sử dụng từ khóa mới để thêm một thành viên -

new (argument-list) = constructor-body

Ví dụ sau minh họa khái niệm -

Thí dụ

Chương trình sau đây tạo một lớp dòng cùng với một hàm tạo tính toán độ dài của dòng khi một đối tượng của lớp được tạo:

type Line = class
   val X1 : float
   val Y1 : float
   val X2 : float
   val Y2 : float

   new (x1, y1, x2, y2) as this =
      { X1 = x1; Y1 = y1; X2 = x2; Y2 = y2;}
      then
         printfn " Creating Line: {(%g, %g), (%g, %g)}\nLength: %g"
            this.X1 this.Y1 this.X2 this.Y2 this.Length

   member x.Length =
      let sqr x = x * x
      sqrt(sqr(x.X1 - x.X2) + sqr(x.Y1 - x.Y2) )
end
let aLine = new Line(1.0, 1.0, 4.0, 5.0)

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Creating Line: {(1, 1), (4, 5)}
Length: 5

Let Bindings

Các ràng buộc let trong định nghĩa lớp cho phép bạn xác định các trường riêng và các hàm riêng cho các lớp F #.

type Greetings(name) as gr =
   let data = name
   do
      gr.PrintMessage()
   member this.PrintMessage() =
      printf "Hello %s\n" data
let gtr = new Greetings("Zara")

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Hello Zara

Xin lưu ý việc sử dụng tự định danh gr cho Greetings lớp.

Một cấu trúc trong F # là một kiểu dữ liệu kiểu giá trị. Nó giúp bạn tạo một biến duy nhất, giữ dữ liệu liên quan của nhiều kiểu dữ liệu khác nhau. Cácstruct từ khóa được sử dụng để tạo cấu trúc.

Cú pháp

Cú pháp để xác định một cấu trúc như sau:

[ attributes ]
type [accessibility-modifier] type-name =
   struct
      type-definition-elements
   end
// or
[ attributes ]
[<StructAttribute>]
type [accessibility-modifier] type-name =
   type-definition-elements

Có hai cú pháp. Cú pháp đầu tiên chủ yếu được sử dụng, bởi vì, nếu bạn sử dụngstructend từ khóa, bạn có thể bỏ qua StructAttribute thuộc tính.

Các yếu tố định nghĩa cấu trúc cung cấp -

  • Tuyên bố thành viên và định nghĩa.
  • Các trình xây dựng và các trường có thể thay đổi và bất biến.
  • Thành viên và triển khai giao diện.

Không giống như các lớp, các cấu trúc không thể được kế thừa và không thể chứa các ràng buộc let hoặc do. Vì, cấu trúc không có ràng buộc; bạn phải khai báo các trường trong cấu trúc bằng cách sử dụngval từ khóa.

Khi bạn xác định một trường và kiểu của nó bằng cách sử dụng valtừ khóa, bạn không thể khởi tạo giá trị trường, thay vào đó chúng được khởi tạo bằng 0 hoặc null. Vì vậy, đối với một cấu trúc có một phương thức khởi tạo ngầm định,val khai báo được chú thích với DefaultValue thuộc tính.

Thí dụ

Chương trình sau đây tạo một cấu trúc dòng cùng với một hàm tạo. Chương trình tính toán độ dài của một dòng bằng cách sử dụng cấu trúc:

type Line = struct
   val X1 : float
   val Y1 : float
   val X2 : float
   val Y2 : float

   new (x1, y1, x2, y2) =
      {X1 = x1; Y1 = y1; X2 = x2; Y2 = y2;}
end
let calcLength(a : Line)=
   let sqr a = a * a
   sqrt(sqr(a.X1 - a.X2) + sqr(a.Y1 - a.Y2) )

let aLine = new Line(1.0, 1.0, 4.0, 5.0)
let length = calcLength aLine
printfn "Length of the Line: %g " length

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Length of the Line: 5

Bạn có thể xác định lại hoặc nạp chồng cho hầu hết các toán tử tích hợp sẵn có trong F #. Do đó, một lập trình viên cũng có thể sử dụng các toán tử với các kiểu do người dùng xác định.

Toán tử là các hàm có tên đặc biệt, được đặt trong dấu ngoặc. Chúng phải được định nghĩa là thành viên lớp tĩnh. Giống như bất kỳ hàm nào khác, toán tử được nạp chồng có kiểu trả về và danh sách tham số.

Ví dụ sau đây, hiển thị một toán tử + trên các số phức:

//overloading + operator
static member (+) (a : Complex, b: Complex) =
Complex(a.x + b.x, a.y + b.y)

Hàm trên thực hiện toán tử cộng (+) cho một lớp Complex do người dùng định nghĩa. Nó thêm các thuộc tính của hai đối tượng và trả về đối tượng Complex kết quả.

Thực hiện quá tải nhà điều hành

Chương trình sau đây cho thấy việc triển khai hoàn chỉnh:

//implementing a complex class with +, and - operators
//overloaded
type Complex(x: float, y : float) =
   member this.x = x
   member this.y = y
   //overloading + operator
   static member (+) (a : Complex, b: Complex) =
      Complex(a.x + b.x, a.y + b.y)

   //overloading - operator
   static member (-) (a : Complex, b: Complex) =
      Complex(a.x - b.x, a.y - b.y)

   // overriding the ToString method
   override this.ToString() =
      this.x.ToString() + " " + this.y.ToString()

//Creating two complex numbers
let c1 = Complex(7.0, 5.0)
let c2 = Complex(4.2, 3.1)

// addition and subtraction using the
//overloaded operators
let c3 = c1 + c2
let c4 = c1 - c2

//printing the complex numbers
printfn "%s" (c1.ToString())
printfn "%s" (c2.ToString())
printfn "%s" (c3.ToString())
printfn "%s" (c4.ToString())

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

7 5
4.2 3.1
11.2 8.1
2.8 1.9

Một trong những khái niệm quan trọng nhất trong lập trình hướng đối tượng là tính kế thừa. Tính kế thừa cho phép chúng ta định nghĩa một lớp theo nghĩa của một lớp khác, giúp tạo và duy trì một ứng dụng dễ dàng hơn. Điều này cũng tạo cơ hội để sử dụng lại chức năng mã và thời gian thực hiện nhanh chóng.

Khi tạo một lớp, thay vì viết các thành viên dữ liệu hoàn toàn mới và các hàm thành viên, lập trình viên có thể chỉ định rằng lớp mới sẽ kế thừa các thành viên của một lớp hiện có. Lớp hiện có này được gọi là lớp cơ sở, và lớp mới được gọi là lớp dẫn xuất.

Ý tưởng kế thừa thực hiện mối quan hệ IS-A. Ví dụ, động vật có vú LÀ Động vật, chó IS-Động vật có vú, do đó chó IS-A động vật cũng như vậy.

Lớp cơ sở và Lớp phụ

Một lớp con có nguồn gốc từ một lớp cơ sở, lớp này đã được định nghĩa. Một lớp con kế thừa các thành viên của lớp cơ sở, cũng như có các thành viên của riêng nó.

Một lớp con được xác định bằng cách sử dụng inherit từ khóa như hình bên dưới -

type MyDerived(...) =
   inherit MyBase(...)

Trong F #, một lớp có thể có nhiều nhất một lớp cơ sở trực tiếp. Nếu bạn không chỉ định một lớp cơ sở bằng cách sử dụnginherit từ khóa, lớp kế thừa ngầm định từ Object.

Xin lưu ý -

  • Các phương thức và thành viên của lớp cơ sở có sẵn cho người dùng của lớp dẫn xuất giống như các thành viên trực tiếp của lớp dẫn xuất.

  • Hãy để các ràng buộc và tham số hàm tạo là riêng tư đối với một lớp và do đó, không thể được truy cập từ các lớp dẫn xuất.

  • Từ khóa baseđề cập đến cá thể lớp cơ sở. Nó được sử dụng giống như mã định danh tự.

Thí dụ

type Person(name) =
   member x.Name = name
   member x.Greet() = printfn "Hi, I'm %s" x.Name

type Student(name, studentID : int) =
   inherit Person(name)
   let mutable _GPA = 0.0
   member x.StudentID = studentID
   member x.GPA
      with get() = _GPA
      and set value = _GPA <- value

type Teacher(name, expertise : string) =
   inherit Person(name)

   let mutable _salary = 0.0
   member x.Salary
      with get() = _salary
      and set value = _salary <- value
   member x.Expertise = expertise

//using the subclasses
let p = new Person("Mohan")
let st = new Student("Zara", 1234)
let tr = new Teacher("Mariam", "Java")

p.Greet()
st.Greet()
tr.Greet()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Hi, I'm Mohan
Hi, I'm Zara
Hi, I'm Mariam

Phương pháp ghi đè

Bạn có thể ghi đè một hành vi mặc định của một phương thức lớp cơ sở và triển khai nó theo cách khác trong lớp con hoặc lớp dẫn xuất.

Các phương thức trong F # không được ghi đè theo mặc định.

Để ghi đè các phương thức trong một lớp dẫn xuất, bạn phải khai báo phương thức của mình là có thể ghi đè bằng cách sử dụng abstractdefault từ khóa như sau -

type Person(name) =
   member x.Name = name
   abstract Greet : unit -> unit
   default x.Greet() = printfn "Hi, I'm %s" x.Name

Bây giờ, phương thức Greet của lớp Person có thể được ghi đè trong các lớp dẫn xuất. Ví dụ sau đây chứng minh điều này -

Thí dụ

type Person(name) =
   member x.Name = name
   abstract Greet : unit -> unit
   default x.Greet() = printfn "Hi, I'm %s" x.Name

type Student(name, studentID : int) =
   inherit Person(name)

   let mutable _GPA = 0.0

   member x.StudentID = studentID
   member x.GPA
      with get() = _GPA
      and set value = _GPA <- value
   override x.Greet() = printfn "Student %s" x.Name

type Teacher(name, expertise : string) =
   inherit Person(name)
   let mutable _salary = 0.0
   member x.Salary
      with get() = _salary
      and set value = _salary <- value

   member x.Expertise = expertise
   override x.Greet() = printfn "Teacher %s." x.Name

//using the subclasses
let p = new Person("Mohan")
let st = new Student("Zara", 1234)
let tr = new Teacher("Mariam", "Java")

//default Greet
p.Greet()

//Overriden Greet
st.Greet()
tr.Greet()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Hi, I'm Mohan
Student Zara
Teacher Mariam.

Lớp trừu tượng

Đôi khi, bạn cần cung cấp một bản triển khai không đầy đủ của một đối tượng, điều này không nên được triển khai trong thực tế. Sau đó, một số lập trình viên khác nên tạo các lớp con của lớp trừu tượng để thực hiện hoàn chỉnh.

Ví dụ, lớp Person sẽ không cần thiết trong Hệ thống quản lý trường học. Tuy nhiên, học viên hoặc giáo viên sẽ là cần thiết. Trong những trường hợp như vậy, bạn có thể khai báo lớp Person là một lớp trừu tượng.

Các AbstractClass thuộc tính cho trình biên dịch biết rằng lớp có một số thành viên trừu tượng.

Bạn không thể tạo một thể hiện của một lớp trừu tượng vì lớp đó không được triển khai đầy đủ.

Ví dụ sau đây chứng minh điều này -

Thí dụ

[<AbstractClass>]
type Person(name) =
   member x.Name = name
   abstract Greet : unit -> unit

type Student(name, studentID : int) =
   inherit Person(name)
   let mutable _GPA = 0.0
   member x.StudentID = studentID
   member x.GPA
      with get() = _GPA
      and set value = _GPA <- value
   override x.Greet() = printfn "Student %s" x.Name

type Teacher(name, expertise : string) =
   inherit Person(name)
   let mutable _salary = 0.0
   member x.Salary
      with get() = _salary
      and set value = _salary <- value
   member x.Expertise = expertise
   override x.Greet() = printfn "Teacher %s." x.Name

let st = new Student("Zara", 1234)
let tr = new Teacher("Mariam", "Java")

//Overriden Greet
st.Greet()
tr.Greet()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Student Zara
Teacher Mariam.

Interfaces cung cấp một cách trừu tượng để viết lên các chi tiết triển khai của một lớp. Nó là một khuôn mẫu khai báo các phương thức mà lớp phải triển khai và hiển thị công khai.

Cú pháp

Một giao diện chỉ định tập hợp các thành viên liên quan mà các lớp khác thực hiện. Nó có cú pháp sau:

// Interface declaration:
[ attributes ]
type interface-name =
   [ interface ]
      [ inherit base-interface-name ...]
      abstract member1 : [ argument-types1 -> ] return-type1
      abstract member2 : [ argument-types2 -> ] return-type2
      ...
   [ end ]
	
// Implementing, inside a class type definition:
interface interface-name with
   member self-identifier.member1 argument-list = method-body1
   member self-identifier.member2 argument-list = method-body2
// Implementing, by using an object expression:
[ attributes ]
let class-name (argument-list) =
   { new interface-name with
      member self-identifier.member1 argument-list = method-body1
      member self-identifier.member2 argument-list = method-body2
      [ base-interface-definitions ]
   }
member-list

Xin lưu ý -

  • Trong một khai báo giao diện, các thành viên không được thực hiện.

  • Các thành viên là trừu tượng, được khai báo bởi abstracttừ khóa. Tuy nhiên, bạn có thể cung cấp một triển khai mặc định bằng cách sử dụngdefault từ khóa.

  • Bạn có thể triển khai các giao diện bằng cách sử dụng các biểu thức đối tượng hoặc bằng cách sử dụng các loại lớp.

  • Trong triển khai lớp hoặc đối tượng, bạn cần cung cấp các thân phương thức cho các phương thức trừu tượng của giao diện.

  • Các từ khóa interfaceend, đánh dấu phần đầu và phần cuối của định nghĩa, là tùy chọn.

Ví dụ,

type IPerson =
   abstract Name : string
   abstract Enter : unit -> unit
   abstract Leave : unit -> unit

Gọi phương thức giao diện

Các phương thức giao diện được gọi thông qua giao diện, không phải thông qua thể hiện của lớp hoặc giao diện thực thi kiểu. Để gọi một phương thức giao diện, bạn lên kiểu giao diện bằng cách sử dụng:> nhà điều hành (upcast operator).

Ví dụ,

(s :> IPerson).Enter()
(s :> IPerson).Leave()

Ví dụ sau minh họa khái niệm -

Thí dụ

type IPerson =
   abstract Name : string
   abstract Enter : unit -> unit
   abstract Leave : unit -> unit

type Student(name : string, id : int) =
   member this.ID = id
   interface IPerson with
      member this.Name = name
      member this.Enter() = printfn "Student entering premises!"
      member this.Leave() = printfn "Student leaving premises!"

type StuffMember(name : string, id : int, salary : float) =
   let mutable _salary = salary

   member this.Salary
      with get() = _salary
      and set(value) = _salary <- value

   interface IPerson with
      member this.Name = name
      member this.Enter() = printfn "Stuff member entering premises!"
      member this.Leave() = printfn "Stuff member leaving premises!"

let s = new Student("Zara", 1234)
let st = new StuffMember("Rohit", 34, 50000.0)

(s :> IPerson).Enter()
(s :> IPerson).Leave()
(st :> IPerson).Enter()
(st :> IPerson).Leave()

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Student entering premises!
Student leaving premises!
Stuff member entering premises!
Stuff member leaving premises!

Kế thừa giao diện

Các giao diện có thể kế thừa từ một hoặc nhiều giao diện cơ sở.

Ví dụ sau đây cho thấy khái niệm -

type Interface1 =
   abstract member doubleIt: int -> int

type Interface2 =
   abstract member tripleIt: int -> int

type Interface3 =
   inherit Interface1
   inherit Interface2
   abstract member printIt: int -> string

type multiplierClass() =
   interface Interface3 with
      member this.doubleIt(a) = 2 * a
      member this.tripleIt(a) = 3 * a
      member this.printIt(a) = a.ToString()

let ml = multiplierClass()
printfn "%d" ((ml:>Interface3).doubleIt(5))
printfn "%d" ((ml:>Interface3).tripleIt(5))
printfn "%s" ((ml:>Interface3).printIt(5))

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

10
15
5

Sự kiện cho phép các lớp gửi và nhận tin nhắn giữa các lớp khác.

Trong GUI, các sự kiện là các hành động của người dùng như nhấn phím, nhấp chuột, di chuyển chuột, v.v. hoặc một số sự kiện như thông báo do hệ thống tạo. Các ứng dụng cần phản hồi các sự kiện khi chúng xảy ra. Ví dụ, ngắt. Sự kiện được sử dụng để giao tiếp giữa các quá trình.

Các đối tượng giao tiếp với nhau thông qua truyền thông điệp đồng bộ.

Sự kiện được đính kèm với các chức năng khác; đối tượng đăng kýcallback các hàm đối với một sự kiện và các lệnh gọi lại này được thực thi khi (và nếu) sự kiện được kích hoạt bởi một số đối tượng.

Lớp Sự kiện và Mô-đun Sự kiện

Lớp Control.Event <'T> giúp tạo một đối tượng hoặc sự kiện có thể quan sát được.

Nó có các thành viên phiên bản sau để làm việc với các sự kiện:

Thành viên Sự miêu tả
Công bố Xuất bản một quan sát dưới dạng giá trị hạng nhất.
Kích hoạt Kích hoạt một quan sát bằng cách sử dụng các tham số đã cho.

Mô-đun Control.Event cung cấp các chức năng để quản lý các luồng sự kiện -

Giá trị Sự miêu tả
thêm: ('T → đơn vị) → Sự kiện <' Del, 'T> → đơn vị Chạy chức năng đã cho mỗi khi sự kiện nhất định được kích hoạt.
chọn: ('T →' U option) → IEvent <'Del,' T> → IEvent <'U> Trả về một sự kiện mới kích hoạt trên một loạt các tin nhắn từ sự kiện ban đầu. Chức năng lựa chọn đưa một tin nhắn gốc sang một tin nhắn mới tùy chọn.
bộ lọc: ('T → bool) → IEvent <' Del, 'T> → IEvent <' T> Trả về một sự kiện mới lắng nghe sự kiện ban đầu và chỉ kích hoạt sự kiện kết quả khi đối số của sự kiện chuyển qua hàm đã cho.
map: ('T →' U) → IEvent <'Del,' T> → IEvent <'U> Trả về một sự kiện mới chuyển các giá trị được biến đổi bởi hàm đã cho.
hợp nhất: IEvent <'Del1,' T> → IEvent <'Del2,' T> → IEvent <'T> Kích hoạt sự kiện đầu ra khi một trong hai sự kiện đầu vào kích hoạt.
theo cặp: IEvent <'Del,' T> → IEvent <'T *' T> Trả về một sự kiện mới kích hoạt vào lần kích hoạt thứ hai và tiếp theo của sự kiện đầu vào. CácNth việc kích hoạt sự kiện đầu vào sẽ chuyển các đối số từ N-1thNthkích hoạt như một cặp. Đối số được chuyển choN-1th kích hoạt được giữ ở trạng thái ẩn bên trong cho đến khi Nth sự kích hoạt xảy ra.
phân vùng: ('T → bool) → IEvent <' Del, 'T> → IEvent <' T> * IEvent <'T> Trả về một sự kiện mới lắng nghe sự kiện ban đầu và kích hoạt sự kiện kết quả đầu tiên nếu ứng dụng của vị từ cho các đối số sự kiện trả về true và sự kiện thứ hai nếu nó trả về false.
quét: ('U →' T → 'U) →' U → IEvent <'Del,' T> → IEvent <'U> Trả về một sự kiện mới bao gồm kết quả của việc áp dụng hàm tích lũy đã cho cho các giá trị liên tiếp được kích hoạt trên sự kiện đầu vào. Một mục của trạng thái bên trong ghi lại giá trị hiện tại của tham số trạng thái. Trạng thái bên trong không bị khóa trong quá trình thực hiện chức năng tích lũy, vì vậy cần cẩn thận để IEvent đầu vào không được kích hoạt bởi nhiều luồng đồng thời.
split: ('T → Choice <' U1, 'U2>) → IEvent <' Del, 'T> → IEvent <' U1> * IEvent <'U2> Trả về một sự kiện mới lắng nghe sự kiện ban đầu và kích hoạt sự kiện kết quả đầu tiên nếu ứng dụng của hàm cho các đối số sự kiện trả về Choice1Of2 và sự kiện thứ hai nếu nó trả về Choice2Of2.

Tạo sự kiện

Các sự kiện được tạo và sử dụng thông qua Eventlớp học. Hàm tạo sự kiện được sử dụng để tạo sự kiện.

Thí dụ

type Worker(name : string, shift : string) =
   let mutable _name = name;
   let mutable _shift = shift;
   let nameChanged = new Event<unit>() (* creates event *)
   let shiftChanged = new Event<unit>() (* creates event *)

   member this.Name
      with get() = _name
      and set(value) = _name <- value

   member this.Shift
      with get() = _shift
      and set(value) = _shift <- value

Sau đó, bạn cần hiển thị trường nameChanged dưới dạng thành viên công khai, để người nghe có thể theo dõi sự kiện mà bạn sử dụng Publish tài sản của sự kiện -

type Worker(name : string, shift : string) =
   let mutable _name = name;
   let mutable _shift = shift;

   let nameChanged = new Event<unit>() (* creates event *)
   let shiftChanged = new Event<unit>() (* creates event *)

   member this.NameChanged = nameChanged.Publish (* exposed event handler *)
   member this.ShiftChanged = shiftChanged.Publish (* exposed event handler *)

   member this.Name
      with get() = _name
      and set(value) = _name <- value
      nameChanged.Trigger() (* invokes event handler *)

   member this.Shift
      with get() = _shift
      and set(value) = _shift <- value
   shiftChanged.Trigger() (* invokes event handler *)

Tiếp theo, bạn thêm lệnh gọi lại vào trình xử lý sự kiện. Mỗi trình xử lý sự kiện có kiểu IEvent <'T>, cung cấp một số phương thức:

phương pháp Sự miêu tả
val Thêm: sự kiện :( 'T → đơn vị) → đơn vị Kết nối chức năng người nghe với sự kiện. Người nghe sẽ được gọi khi sự kiện được kích hoạt.
val AddHandler: 'del → đơn vị Kết nối một đối tượng ủy quyền của trình xử lý với sự kiện. Một trình xử lý có thể được gỡ bỏ sau đó bằng cách sử dụng RemoveHandler. Người nghe sẽ được gọi khi sự kiện được kích hoạt.
val RemoveHandler: 'del → đơn vị Xóa đại biểu người nghe khỏi kho lưu trữ trình nghe sự kiện.

Phần sau cung cấp một ví dụ đầy đủ.

Thí dụ

Ví dụ sau minh họa khái niệm và kỹ thuật được thảo luận ở trên:

type Worker(name : string, shift : string) =
   let mutable _name = name;
   let mutable _shift = shift;

   let nameChanged = new Event<unit>() (* creates event *)
   let shiftChanged = new Event<unit>() (* creates event *)

   member this.NameChanged = nameChanged.Publish (* exposed event handler *)
   member this.ShiftChanged = shiftChanged.Publish (* exposed event handler *)

   member this.Name
      with get() = _name
      and set(value) = 
         _name <- value
         nameChanged.Trigger() (* invokes event handler *)

   member this.Shift
      with get() = _shift
      and set(value) = 
         _shift <- value
         shiftChanged.Trigger() (* invokes event handler *)

let wk = new Worker("Wilson", "Evening")
wk.NameChanged.Add(fun () -> printfn "Worker changed name! New name: %s" wk.Name)
wk.Name <- "William"
wk.NameChanged.Add(fun () -> printfn "-- Another handler attached to NameChanged!")
wk.Name <- "Bill"

wk.ShiftChanged.Add(fun () -> printfn "Worker changed shift! New shift: %s" wk.Shift)
wk.Shift <- "Morning"
wk.ShiftChanged.Add(fun () -> printfn "-- Another handler attached to ShiftChanged!")
wk.Shift <- "Night"

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Worker changed name! New name: William
Worker changed name! New name: Bill
-- Another handler attached to NameChanged!
Worker changed shift! New shift: Morning
Worker changed shift! New shift: Night
-- Another handler attached to ShiftChanged!

Theo thư viện MSDN, mô-đun F # là một nhóm các cấu trúc mã F #, chẳng hạn như kiểu, giá trị, giá trị hàm và mã trong các ràng buộc thực hiện. Nó được triển khai như một lớp thời gian chạy ngôn ngữ chung (CLR) chỉ có các thành viên tĩnh.

Tùy thuộc vào tình huống toàn bộ tệp có được bao gồm trong mô-đun hay không, có hai loại khai báo mô-đun:

  • Khai báo mô-đun cấp cao nhất
  • Khai báo mô-đun cục bộ

Trong khai báo mô-đun cấp cao nhất, toàn bộ tệp được bao gồm trong mô-đun. Trong trường hợp này, khai báo đầu tiên trong tệp là khai báo mô-đun. Bạn không phải thụt lề khai báo trong mô-đun cấp cao nhất.

Trong khai báo mô-đun cục bộ, chỉ các khai báo được thụt vào trong khai báo mô-đun đó là một phần của mô-đun.

Cú pháp

Cú pháp khai báo mô-đun như sau:

// Top-level module declaration.
module [accessibility-modifier] [qualified-namespace.]module-name
   declarations
// Local module declaration.
module [accessibility-modifier] module-name =
   declarations

Xin lưu ý rằng công cụ sửa đổi trợ năng có thể là một trong những công cụ sau - công khai, riêng tư, nội bộ. Mặc định làpublic.

Các ví dụ sau đây sẽ chứng minh các khái niệm -

ví dụ 1

Tệp mô-đun Arithmetic.fs -

module Arithmetic
let add x y =
   x + y

let sub x y =
   x - y
	
let mult x y =
   x * y
	
let div x y =
   x / y

Tệp chương trình main.fs -

// Fully qualify the function name.
open Arithmetic
let addRes = Arithmetic.add 25 9
let subRes = Arithmetic.sub 25 9
let multRes = Arithmetic.mult 25 9
let divRes = Arithmetic.div 25 9

printfn "%d" addRes
printfn "%d" subRes
printfn "%d" multRes
printfn "%d" divRes

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

34
16
225
2
110
90
1000
10

Ví dụ 2

// Module1
module module1 =
   // Indent all program elements within modules that are declared with an equal sign.
   let value1 = 100
   let module1Function x =
      x + value1

// Module2
module module2 =
   let value2 = 200

   // Use a qualified name to access the function.
   // from module1.
   let module2Function x =
      x + (module1.module1Function value2)

let result = module1.module1Function 25
printfn "%d" result

let result2 = module2.module2Function 25
printfn "%d" result2

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

125
325

A namespaceđược thiết kế để cung cấp một cách để giữ cho một bộ tên riêng biệt với một bộ tên khác. Tên lớp được khai báo trong một không gian tên sẽ không xung đột với các tên lớp tương tự được khai báo trong vùng tên khác.

Theo thư viện MSDN, namespace cho phép bạn tổ chức mã thành các khu vực chức năng liên quan bằng cách cho phép bạn đính kèm tên vào nhóm các phần tử chương trình.

Khai báo không gian tên

Để tổ chức mã của bạn trong một không gian tên, bạn phải khai báo không gian tên như phần khai báo đầu tiên trong tệp. Nội dung của toàn bộ tệp sau đó trở thành một phần của không gian tên.

namespace [parent-namespaces.]identifier

Ví dụ sau minh họa khái niệm -

Thí dụ

namespace testing

module testmodule1 =
   let testFunction x y =
      printfn "Values from Module1: %A %A" x y
module testmodule2 =
   let testFunction x y =
      printfn "Values from Module2: %A %A" x y

module usermodule =
   do
      testmodule1.testFunction ( "one", "two", "three" ) 150
      testmodule2.testFunction (seq { for i in 1 .. 10 do yield i * i }) 200

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Values from Module1: ("one", "two", "three") 150
Values from Module2: seq [1; 4; 9; 16; ...] 200