F # - คู่มือฉบับย่อ
F # เป็นภาษาโปรแกรมที่ใช้งานได้ เพื่อให้เข้าใจโครงสร้าง F # คุณต้องอ่านสองสามบรรทัดเกี่ยวกับกระบวนทัศน์การเขียนโปรแกรมที่ตั้งชื่อFunctional Programming.
การเขียนโปรแกรมเชิงฟังก์ชันถือว่าโปรแกรมคอมพิวเตอร์เป็นฟังก์ชันทางคณิตศาสตร์ ในการเขียนโปรแกรมเชิงฟังก์ชันโฟกัสจะอยู่ที่ค่าคงที่และฟังก์ชันแทนที่จะเป็นตัวแปรและสถานะ เนื่องจากฟังก์ชันและค่าคงที่เป็นสิ่งที่ไม่เปลี่ยนแปลง
ในการเขียนโปรแกรมเชิงฟังก์ชันคุณจะต้องเขียนโปรแกรมแบบแยกส่วนกล่าวคือโปรแกรมจะประกอบด้วยฟังก์ชันที่จะใช้ฟังก์ชันอื่นเป็นอินพุต
โปรแกรมที่เขียนด้วยภาษาโปรแกรมเชิงฟังก์ชันมักจะกระชับ
เกี่ยวกับ F #
ต่อไปนี้เป็นข้อมูลพื้นฐานเกี่ยวกับ F # -
- ได้รับการพัฒนาในปี 2548 ที่ Microsoft Research
- เป็นส่วนหนึ่งของตระกูลภาษา. Net ของ Microsoft
- มันเป็นภาษาโปรแกรมที่ใช้งานได้
- มันขึ้นอยู่กับภาษาการเขียนโปรแกรมที่ใช้งานได้ OCaml
คุณสมบัติของ F #
มันคือการใช้งาน. Net ของ OCaml
รวบรวมรหัสไบต์. Net CLI (Common Language Interface) หรือ MSIL (Microsoft Intermediate Language) ที่ทำงานบน CLR (Common Language Runtime)
ให้การอนุมานประเภท
มีโครงสร้างการจับคู่รูปแบบที่หลากหลาย
มีความสามารถในการเขียนสคริปต์แบบโต้ตอบและการดีบัก
ช่วยให้สามารถเขียนฟังก์ชันลำดับที่สูงขึ้น
มีรูปแบบวัตถุที่พัฒนามาอย่างดี
การใช้ F #
โดยปกติจะใช้ F # ในพื้นที่ต่อไปนี้ -
- สร้างแบบจำลองทางวิทยาศาสตร์
- การแก้ปัญหาทางคณิตศาสตร์
- งานวิจัยปัญญาประดิษฐ์
- การสร้างแบบจำลองทางการเงิน
- การออกแบบกราฟิก
- การออกแบบ CPU
- การเขียนโปรแกรมคอมไพเลอร์
- Telecommunications
นอกจากนี้ยังใช้ในแอป CRUD หน้าเว็บเกม GUI และโปรแกรมวัตถุประสงค์ทั่วไปอื่น ๆ
เครื่องมือที่จำเป็นสำหรับการเขียนโปรแกรม F # จะกล่าวถึงในบทนี้
Integrated Development Environment (IDE) สำหรับ F #
Microsoft จัดเตรียม Visual Studio 2013 สำหรับการเขียนโปรแกรม F #
Visual Studio 2013 Community Edition ฟรีมีให้จากเว็บไซต์ทางการของ Microsoft Visual Studio 2013 Community ขึ้นไปมาพร้อมกับ Visual F # Tools ดูรายละเอียดการติดตั้งได้ที่Asp.net Tutorialเครื่องมือ Visual F # ประกอบด้วยคอมไพเลอร์บรรทัดคำสั่ง (fsc.exe) และ F # Interactive (fsi.exe)
ด้วยการใช้เครื่องมือเหล่านี้คุณสามารถเขียนโปรแกรม F # ได้ทุกประเภทตั้งแต่แอปพลิเคชันบรรทัดคำสั่งธรรมดาไปจนถึงแอปพลิเคชันที่ซับซ้อนมากขึ้น คุณยังสามารถเขียนไฟล์ซอร์สโค้ด F # โดยใช้โปรแกรมแก้ไขข้อความพื้นฐานเช่น Notepad และคอมไพล์โค้ดลงในแอสเซมบลีโดยใช้คอมไพเลอร์บรรทัดคำสั่ง
คุณสามารถดาวน์โหลดได้จาก Microsoft Visual Studio ได้รับการติดตั้งโดยอัตโนมัติในเครื่องของคุณ
การเขียนโปรแกรม F # บนลิงค์
โปรดเยี่ยมชมเว็บไซต์อย่างเป็นทางการของ F # สำหรับคำแนะนำล่าสุดเกี่ยวกับการรับเครื่องมือเป็นแพ็คเกจ Debian หรือรวบรวมโดยตรงจากแหล่งที่มา - https://fsharp.org/use/linux/.
F # เป็นภาษาการเขียนโปรแกรมเชิงฟังก์ชัน
ใน F # ฟังก์ชันจะทำงานเหมือนกับชนิดข้อมูล คุณสามารถประกาศและใช้ฟังก์ชันในลักษณะเดียวกับตัวแปรอื่น ๆ
โดยทั่วไปแอปพลิเคชัน F # ไม่มีจุดเข้าเฉพาะ คอมไพเลอร์รันคำสั่งระดับบนสุดทั้งหมดในไฟล์จากบนลงล่าง
อย่างไรก็ตามเพื่อให้เป็นไปตามรูปแบบการเขียนโปรแกรมขั้นตอนแอปพลิเคชันจำนวนมากจะใช้คำสั่งระดับบนสุดเดียวที่เรียกใช้ลูปหลัก
รหัสต่อไปนี้แสดงโปรแกรม F # อย่างง่าย -
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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
sign 5: positive
โปรดทราบว่า -
ไฟล์รหัส F # อาจขึ้นต้นด้วยไฟล์ open คำสั่งที่ใช้ในการนำเข้าเนมสเปซ
เนื้อหาของไฟล์ประกอบด้วยฟังก์ชันอื่น ๆ ที่ใช้ตรรกะทางธุรกิจของแอปพลิเคชัน
ลูปหลักประกอบด้วยคำสั่งปฏิบัติการอันดับต้น ๆ
คุณได้เห็นโครงสร้างพื้นฐานของโปรแกรม F # แล้วดังนั้นจึงง่ายต่อการเข้าใจส่วนประกอบพื้นฐานอื่น ๆ ของภาษาโปรแกรม F #
โทเค็นใน F #
โปรแกรม F # ประกอบด้วยโทเค็นต่างๆ โทเค็นอาจเป็นคีย์เวิร์ดตัวระบุค่าคงที่สตริงลิเทอรัลหรือสัญลักษณ์ เราสามารถแบ่งประเภทโทเค็น F # ออกเป็นสองประเภท -
- Keywords
- สัญลักษณ์และตัวดำเนินการ
คำหลัก F #
ตารางต่อไปนี้แสดงคำสำคัญและคำอธิบายสั้น ๆ ของคำหลัก เราจะพูดถึงการใช้คำหลักเหล่านี้ในบทต่อ ๆ ไป
คำสำคัญ | คำอธิบาย |
---|---|
abstract | บ่งชี้วิธีการที่ไม่มีการนำไปใช้งานในประเภทที่มีการประกาศหรือที่เป็นเสมือนและมีการใช้งานดีฟอลต์ |
and | ใช้ในการผูกแบบวนซ้ำร่วมกันในการประกาศคุณสมบัติและมีข้อ จำกัด หลายประการเกี่ยวกับพารามิเตอร์ทั่วไป |
as | ใช้เพื่อตั้งชื่ออ็อบเจ็กต์คลาสปัจจุบัน ใช้เพื่อตั้งชื่อให้กับรูปแบบทั้งหมดภายในการจับคู่รูปแบบ |
assert | ใช้เพื่อตรวจสอบรหัสระหว่างการดีบัก |
base | ใช้เป็นชื่อของอ็อบเจ็กต์คลาสพื้นฐาน |
begin | ในไวยากรณ์ verbose ระบุจุดเริ่มต้นของบล็อกรหัส |
class | ในไวยากรณ์ verbose ระบุจุดเริ่มต้นของนิยามคลาส |
default | บ่งชี้ถึงการดำเนินการตามวิธีนามธรรม ใช้ร่วมกับการประกาศวิธีการนามธรรมเพื่อสร้างวิธีการเสมือน |
delegate | ใช้เพื่อประกาศผู้รับมอบสิทธิ์ |
do | ใช้ในการสร้างแบบวนซ้ำหรือเพื่อรันโค้ดที่จำเป็น |
done | ในไวยากรณ์ verbose ระบุจุดสิ้นสุดของรหัสในนิพจน์การวนซ้ำ |
downcast | ใช้เพื่อแปลงเป็นประเภทที่อยู่ต่ำกว่าในห่วงโซ่การสืบทอด |
downto | ใน for นิพจน์ใช้เมื่อนับย้อนกลับ |
elif | ใช้ในการแตกแขนงตามเงื่อนไข รูปแบบสั้น ๆ ของ if |
else | ใช้ในการแตกแขนงตามเงื่อนไข |
end | ในนิยามประเภทและส่วนขยายประเภทระบุจุดสิ้นสุดของส่วนของนิยามสมาชิก ในไวยากรณ์ verbose ใช้เพื่อระบุจุดสิ้นสุดของบล็อกโค้ดที่ขึ้นต้นด้วยคีย์เวิร์ดเริ่มต้น |
exception | ใช้เพื่อประกาศประเภทข้อยกเว้น |
extern | บ่งชี้ว่าองค์ประกอบของโปรแกรมที่ประกาศถูกกำหนดไว้ในไบนารีหรือแอสเซมบลีอื่น |
false | ใช้เป็นลิเทอรัลบูลีน |
finally | ใช้ร่วมกับพยายามแนะนำบล็อกของโค้ดที่ดำเนินการโดยไม่คำนึงว่าจะมีข้อยกเว้นเกิดขึ้นหรือไม่ |
for | ใช้ในการสร้างแบบวนซ้ำ |
fun | ใช้ในนิพจน์แลมบ์ดาหรือที่เรียกว่าฟังก์ชันที่ไม่ระบุชื่อ |
function | ใช้เป็นทางเลือกที่สั้นกว่าสำหรับคีย์เวิร์ด fun และนิพจน์การจับคู่ในนิพจน์แลมบ์ดาที่มีรูปแบบการจับคู่กับอาร์กิวเมนต์เดียว |
global | ใช้เพื่ออ้างอิงเนมสเปซ. NET ระดับบนสุด |
if | ใช้ในโครงสร้างการแยกตามเงื่อนไข |
in | ใช้สำหรับนิพจน์ลำดับและในไวยากรณ์ verbose เพื่อแยกนิพจน์จากการผูก |
inherit | ใช้เพื่อระบุคลาสฐานหรืออินเตอร์เฟสพื้นฐาน |
inline | ใช้เพื่อระบุฟังก์ชันที่ควรรวมเข้ากับรหัสของผู้โทรโดยตรง |
interface | ใช้เพื่อประกาศและใช้งานอินเทอร์เฟซ |
internal | ใช้เพื่อระบุว่าสมาชิกสามารถมองเห็นได้ภายในชุดประกอบ แต่ไม่อยู่ภายนอก |
lazy | ใช้เพื่อระบุการคำนวณที่จะดำเนินการเมื่อต้องการผลลัพธ์เท่านั้น |
let | ใช้เพื่อเชื่อมโยงหรือผูกชื่อกับค่าหรือฟังก์ชัน |
let! | ใช้ในเวิร์กโฟลว์แบบอะซิงโครนัสเพื่อผูกชื่อกับผลลัพธ์ของการคำนวณแบบอะซิงโครนัสหรือในนิพจน์การคำนวณอื่น ๆ ที่ใช้เพื่อผูกชื่อกับผลลัพธ์ซึ่งเป็นประเภทการคำนวณ |
match | ใช้เพื่อแยกสาขาโดยการเปรียบเทียบค่ากับรูปแบบ |
member | ใช้เพื่อประกาศคุณสมบัติหรือเมธอดในประเภทอ็อบเจ็กต์ |
module | ใช้เพื่อเชื่อมโยงชื่อกับกลุ่มของประเภทค่าและฟังก์ชันที่เกี่ยวข้องเพื่อแยกออกจากรหัสอื่นอย่างมีเหตุผล |
mutable | ใช้เพื่อประกาศตัวแปรนั่นคือค่าที่สามารถเปลี่ยนแปลงได้ |
namespace | ใช้เพื่อเชื่อมโยงชื่อกับกลุ่มประเภทและโมดูลที่เกี่ยวข้องเพื่อแยกออกจากรหัสอื่นอย่างมีเหตุผล |
new | ใช้เพื่อประกาศกำหนดหรือเรียกใช้คอนสตรัคเตอร์ที่สร้างหรือที่สามารถสร้างอ็อบเจ็กต์ นอกจากนี้ยังใช้ในข้อ จำกัด พารามิเตอร์ทั่วไปเพื่อระบุว่าชนิดต้องมีตัวสร้างที่แน่นอน |
not | ไม่ใช่คำหลัก อย่างไรก็ตามการไม่ใช้โครงสร้างร่วมกันเป็นข้อ จำกัด ของพารามิเตอร์ทั่วไป |
null | บ่งชี้ว่าไม่มีวัตถุ ยังใช้ในข้อ จำกัด พารามิเตอร์ทั่วไป |
of | ใช้ในสหภาพแรงงานที่เลือกปฏิบัติเพื่อระบุประเภทของค่าต่างๆและในการประกาศผู้ร่วมประชุมและข้อยกเว้น |
open | ใช้เพื่อทำให้เนื้อหาของเนมสเปซหรือโมดูลพร้อมใช้งานโดยไม่มีคุณสมบัติ |
or | ใช้กับเงื่อนไขบูลีนเป็นบูลีนหรือตัวดำเนินการ เทียบเท่ากับ ||. ยังใช้ในข้อ จำกัด ของสมาชิก |
override | ใช้เพื่อใช้เวอร์ชันของวิธีนามธรรมหรือเสมือนที่แตกต่างจากเวอร์ชันพื้นฐาน |
private | จำกัด การเข้าถึงของสมาชิกในรหัสในประเภทหรือโมดูลเดียวกัน |
public | อนุญาตให้เข้าถึงสมาชิกจากภายนอกประเภท |
rec | ใช้เพื่อระบุว่าฟังก์ชันเป็นแบบวนซ้ำ |
return | ใช้เพื่อระบุค่าที่จะให้เป็นผลลัพธ์ของนิพจน์การคำนวณ |
return! | ใช้เพื่อระบุนิพจน์การคำนวณที่เมื่อประเมินแล้วจะให้ผลลัพธ์ของนิพจน์การคำนวณที่มี |
select | ใช้ในนิพจน์แบบสอบถามเพื่อระบุฟิลด์หรือคอลัมน์ที่จะแยก โปรดทราบว่านี่เป็นคำหลักตามบริบทซึ่งหมายความว่าแท้จริงแล้วไม่ใช่คำสงวนและทำหน้าที่เหมือนคำหลักในบริบทที่เหมาะสมเท่านั้น |
static | ใช้เพื่อระบุวิธีการหรือคุณสมบัติที่สามารถเรียกได้โดยไม่ต้องใช้อินสแตนซ์ของชนิดหรือสมาชิกค่าที่ใช้ร่วมกันระหว่างอินสแตนซ์ทั้งหมดของชนิด |
struct | ใช้เพื่อประกาศประเภทโครงสร้าง ยังใช้ในข้อ จำกัด พารามิเตอร์ทั่วไป ใช้สำหรับความเข้ากันได้ของ OCaml ในข้อกำหนดของโมดูล |
then | ใช้ในนิพจน์เงื่อนไข นอกจากนี้ยังใช้เพื่อทำผลข้างเคียงหลังการสร้างวัตถุ |
to | ใช้สำหรับลูปเพื่อระบุช่วง |
true | ใช้เป็นลิเทอรัลบูลีน |
try | ใช้เพื่อแนะนำบล็อกโค้ดที่อาจสร้างข้อยกเว้น ใช้ร่วมกับหรือสุดท้าย. |
type | ใช้เพื่อประกาศคลาสบันทึกโครงสร้างการแบ่งแยกยูเนี่ยนประเภทการแจงนับหน่วยการวัดหรือตัวย่อประเภท |
upcast | ใช้เพื่อแปลงเป็นประเภทที่สูงกว่าในห่วงโซ่การสืบทอด |
use | ใช้แทน let สำหรับค่าที่ต้องการ Dispose เพื่อเรียกใช้ทรัพยากรฟรี |
use! | ใช้แทนให้! ในเวิร์กโฟลว์แบบอะซิงโครนัสและนิพจน์การคำนวณอื่น ๆ สำหรับค่าที่ต้องการ Dispose เพื่อเรียกใช้ทรัพยากรว่าง |
val | ใช้ในลายเซ็นเพื่อระบุค่าหรือในประเภทเพื่อประกาศสมาชิกในสถานการณ์ที่ จำกัด |
void | ระบุชนิดโมฆะ. NET ใช้เมื่อทำงานร่วมกับภาษา. NET อื่น ๆ |
when | ใช้สำหรับเงื่อนไขบูลีน(เมื่อยาม)ในการจับคู่รูปแบบและเพื่อแนะนำประโยคข้อ จำกัด สำหรับพารามิเตอร์ประเภททั่วไป |
while | แนะนำโครงสร้างแบบวนซ้ำ |
with | ใช้ร่วมกับคีย์เวิร์ดที่ตรงกันในนิพจน์การจับคู่รูปแบบ นอกจากนี้ยังใช้ในนิพจน์อ็อบเจ็กต์นิพจน์การคัดลอกบันทึกและประเภทส่วนขยายเพื่อแนะนำนิยามสมาชิกและแนะนำตัวจัดการข้อยกเว้น |
yield | ใช้ในนิพจน์ลำดับเพื่อสร้างค่าสำหรับลำดับ |
yield! | ใช้ในนิพจน์การคำนวณเพื่อต่อท้ายผลลัพธ์ของนิพจน์การคำนวณที่กำหนดเข้ากับคอลเล็กชันของผลลัพธ์สำหรับนิพจน์การคำนวณที่มี |
คำหลักที่สงวนไว้บางคำมาจากภาษา OCaml -
asr | ที่ดิน | ล | lsl | lsr | lxor | mod | ซิก |
คำหลักอื่น ๆ ที่สงวนไว้จะถูกเก็บไว้สำหรับการขยาย F # ในอนาคต
ปรมาณู | หยุดพัก | ตรวจสอบแล้ว | ส่วนประกอบ | const | ข้อ จำกัด | 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
ก tupleคือชุดค่าที่คั่นด้วยจุลภาค สิ่งเหล่านี้ใช้สำหรับการสร้างโครงสร้างข้อมูลเฉพาะกิจซึ่งจัดกลุ่มค่าที่เกี่ยวข้องเข้าด้วยกัน
ตัวอย่างเช่น (“ Zara Ali”,“ Hyderabad”, 10) คือ 3-tuple ที่มีค่าสตริงสองค่าและค่า int มีประเภท (string * string * int)
Tuples อาจเป็นคู่สามเท่าและอื่น ๆ ประเภทเดียวกันหรือต่างกัน
ตัวอย่างบางส่วนมีให้ที่นี่ -
// 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)
ตัวอย่าง
โปรแกรมนี้มีฟังก์ชันที่รับค่าทศนิยมสี่ค่าและส่งกลับค่าเฉลี่ย -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Avg of four numbers: 7.275000
การเข้าถึงสมาชิกทูเพิลแต่ละคน
สมาชิกแต่ละคนของทูเปิลสามารถประเมินและพิมพ์โดยใช้การจับคู่รูปแบบ
ตัวอย่างต่อไปนี้แสดงแนวคิด -
ตัวอย่าง
let display tuple1 =
match tuple1 with
| (a, b, c) -> printfn "Detail Info: %A %A %A" a b c
display ("Zara Ali", "Hyderabad", 10 )
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Detail Info: "Zara Ali" "Hyderabad" 10
F # มีสองฟังก์ชันในตัว fst และ snd, ซึ่งส่งคืนรายการแรกและรายการที่สองในทูเพิล
ตัวอย่างต่อไปนี้แสดงแนวคิด -
ตัวอย่าง
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)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
First member: 23
Second member: 30
First member: "Hello"
Second member: "World!"
First Name: "Zara"
Second Name: "Ali"
ก recordคล้ายกับทูเปิล แต่มีฟิลด์ที่มีชื่อ ตัวอย่างเช่น,
type website =
{ title : string;
url : string }
การกำหนดบันทึก
บันทึกถูกกำหนดเป็นประเภทโดยใช้ type คีย์เวิร์ดและฟิลด์ของเร็กคอร์ดถูกกำหนดให้เป็นรายการที่คั่นด้วยอัฒภาค
ไวยากรณ์สำหรับการกำหนดระเบียนคือ -
type recordName =
{ [ fieldName : dataType ] + }
การสร้างบันทึก
คุณสามารถสร้างเรกคอร์ดโดยระบุฟิลด์ของเรกคอร์ด ตัวอย่างเช่นให้เราสร้างบันทึกเว็บไซต์ชื่อโฮมเพจ -
let homepage = { Title = "TutorialsPoint"; Url = "www.tutorialspoint.com" }
ตัวอย่างต่อไปนี้จะอธิบายแนวคิด -
ตัวอย่าง 1
โปรแกรมนี้กำหนดประเภทบันทึกชื่อเว็บไซต์ จากนั้นจะสร้างบันทึกบางประเภทของเว็บไซต์และพิมพ์บันทึก
(* 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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"
ตัวอย่าง 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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Before Registration: : {Name = "Zara";
ID = 10;
RegistrationText = null;
IsRegistered = false;}
After Registration: : {Name = "Zara";
ID = 10;
RegistrationText = "Registered";
IsRegistered = true;}
ใน F # รายการคือชุดขององค์ประกอบประเภทเดียวกันที่เรียงลำดับและไม่เปลี่ยนรูป มีขอบเขตเทียบเท่ากับโครงสร้างข้อมูลรายการที่เชื่อมโยง
โมดูล F # Microsoft.FSharp.Collections.List,มีการดำเนินการทั่วไปในรายการ อย่างไรก็ตาม F # จะนำเข้าโมดูลนี้โดยอัตโนมัติและทำให้ทุกแอปพลิเคชัน F # สามารถเข้าถึงได้
การสร้างและเริ่มต้นรายการ
ต่อไปนี้เป็นวิธีต่างๆในการสร้างรายการ -
การใช้รายการ literals.
การใช้ cons (: :) ตัวดำเนินการ
ใช้ List.init วิธีการของโมดูลรายการ
ใช้ syntactic constructs เรียกว่า List Comprehensions.
แสดงรายการตัวอักษร
ในวิธีนี้คุณเพียงระบุลำดับค่าที่คั่นด้วยอัฒภาคในวงเล็บเหลี่ยม ตัวอย่างเช่น -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
ข้อเสีย (: :) Operator
ด้วยวิธีนี้คุณสามารถเพิ่มค่าบางอย่างได้โดยการเติมเงินล่วงหน้าหรือ cons-ingไปยังรายการที่มีอยู่โดยใช้ตัวดำเนินการ :: ตัวอย่างเช่น -
let list2 = 1::2::3::4::5::6::7::8::9::10::[];;
[] หมายถึงรายการว่าง
วิธีเริ่มรายการ
เมธอด List.init ของโมดูลรายการมักใช้ในการสร้างรายการ วิธีนี้มีประเภท -
val init : int -> (int -> 'T) -> 'T list
อาร์กิวเมนต์แรกคือความยาวที่ต้องการของรายการใหม่และอาร์กิวเมนต์ที่สองคือฟังก์ชัน initializer ซึ่งสร้างรายการในรายการ
ตัวอย่างเช่น,
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
ที่นี่ฟังก์ชันดัชนีจะสร้างรายการ
แสดงรายการความเข้าใจ
ความเข้าใจในรายการเป็นโครงสร้างทางวากยสัมพันธ์พิเศษที่ใช้ในการสร้างรายการ
ไวยากรณ์ความเข้าใจของรายการ F # มีสองรูปแบบ - ช่วงและตัวสร้าง
ช่วงมีโครงสร้าง - [start .. end] และ [start .. step .. end]
ตัวอย่างเช่น,
let list3 = [1 .. 10]
เครื่องกำเนิดไฟฟ้ามีโครงสร้าง - [สำหรับ x ในคอลเลกชันทำ ... อัตราผลตอบแทน]
ตัวอย่างเช่น,
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
ในฐานะที่เป็น yield คำหลักผลักค่าเดียวลงในรายการคำหลัก yield!, ผลักดันคอลเลกชันของค่าลงในรายการ
ฟังก์ชันต่อไปนี้แสดงให้เห็นถึงวิธีการข้างต้น -
ตัวอย่าง
(* 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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]
คุณสมบัติของประเภทข้อมูลรายการ
ตารางต่อไปนี้แสดงคุณสมบัติต่างๆของชนิดข้อมูลรายการ -
ทรัพย์สิน | ประเภท | คำอธิบาย |
---|---|---|
ศีรษะ | 'ท | องค์ประกอบแรก |
ว่างเปล่า | รายการ 'T | คุณสมบัติคงที่ที่ส่งคืนรายการว่างของชนิดที่เหมาะสม |
มันว่างเปล่า | บูล | true หากรายการไม่มีองค์ประกอบ |
สิ่งของ | 'ท | องค์ประกอบที่ดัชนีที่ระบุ (อิงศูนย์) |
ความยาว | int | จำนวนองค์ประกอบ |
หาง | รายการ 'T | รายการที่ไม่มีองค์ประกอบแรก |
ตัวอย่างต่อไปนี้แสดงการใช้คุณสมบัติเหล่านี้ -
ตัวอย่าง
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))
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
ตัวดำเนินการพื้นฐานในรายการ
ตารางต่อไปนี้แสดงการดำเนินการพื้นฐานเกี่ยวกับชนิดข้อมูลรายการ -
มูลค่า | คำอธิบาย |
---|---|
ผนวก: 'T list →' T list → 'T list | ส่งคืนรายการใหม่ที่มีองค์ประกอบของรายการแรกตามด้วยองค์ประกอบของรายการที่สอง |
ค่าเฉลี่ย: รายการ T → ^ T | ส่งคืนค่าเฉลี่ยขององค์ประกอบในรายการ |
averageBy: ('T → ^ U) →' T list → ^ U | ส่งกลับค่าเฉลี่ยขององค์ประกอบที่สร้างขึ้นโดยใช้ฟังก์ชันกับแต่ละองค์ประกอบของรายการ |
เลือก: ('T →' ตัวเลือก U) → 'T list →' รายการ U | ใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของรายการ ส่งคืนรายการที่ประกอบด้วยผลลัพธ์สำหรับแต่ละองค์ประกอบที่ฟังก์ชันส่งคืนSome. |
รวบรวม: ('T →' รายการ U) → 'T รายการ→' รายการ U | สำหรับแต่ละองค์ประกอบของรายการให้ใช้ฟังก์ชันที่กำหนด เชื่อมต่อผลลัพธ์ทั้งหมดและส่งคืนรายการที่รวมกัน |
concat: seq <'T list> →' T list | ส่งคืนรายการใหม่ที่มีองค์ประกอบของแต่ละรายการตามลำดับ |
ว่างเปล่า: รายการ T | ส่งคืนรายการว่างของประเภทที่กำหนด |
มีอยู่: ('T → bool) →' T list → bool | ทดสอบว่าองค์ประกอบใดของรายการตรงตามเพรดิเคตที่กำหนดหรือไม่ |
มีอยู่ 2: ('T1 →' T2 →บูล) → 'รายการ T1 →' รายการ T2 →บูล | ทดสอบว่าคู่ขององค์ประกอบที่เกี่ยวข้องของรายการตรงตามเพรดิเคตที่กำหนดหรือไม่ |
ฟิลเตอร์: ('T → bool) →' T list → 'T list | ส่งคืนคอลเล็กชันใหม่ที่มีเฉพาะองค์ประกอบของคอลเล็กชันที่เพรดิเคตที่ระบุส่งคืน true. |
ค้นหา: ('T → bool) →' T list → 'T | ส่งคืนองค์ประกอบแรกที่ฟังก์ชันที่กำหนดส่งคืน true. |
findIndex: ('T → bool) →' T list → int | ส่งคืนดัชนีขององค์ประกอบแรกในรายการที่ตรงตามเพรดิเคตที่กำหนด |
พับ: ('State →' T → 'State) →' State → 'T list →' State | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของคอลเลกชันโดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ ฟังก์ชันนี้รับอาร์กิวเมนต์ที่สองและใช้ฟังก์ชันกับมันและองค์ประกอบแรกของรายการ จากนั้นจะส่งผ่านผลลัพธ์นี้ไปยังฟังก์ชันพร้อมกับองค์ประกอบที่สองและอื่น ๆ สุดท้ายก็ส่งกลับผลลัพธ์สุดท้าย หากฟังก์ชันอินพุตคือ f และองค์ประกอบคือ i0 ... iN ฟังก์ชันนี้จะคำนวณ f (... (fs i0) i1 ... ) iN |
fold2: ('State →' T1 → 'T2 →' State) → 'State →' T1 list → 'T2 list →' State | ใช้ฟังก์ชันกับองค์ประกอบที่สอดคล้องกันของสองคอลเลกชันโดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ คอลเล็กชันต้องมีขนาดเท่ากัน หากฟังก์ชันอินพุตเป็น f และองค์ประกอบคือ i0 ... iN และ j0 ... jN ฟังก์ชันนี้จะคำนวณ f (... (fs i0 j0) ... ) iN jN |
foldBack: ('T →' State → 'State) →' T list → 'State →' State | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของคอลเลกชันโดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ ถ้าฟังก์ชันอินพุต isf และอิลิเมนต์คือ i0 ... iN ให้คำนวณ f i0 (... (f iN s)) |
foldBack2: ('T1 →' T2 → 'รัฐ→' รัฐ) → 'รายการ T1 →' รายการ T2 → 'รัฐ→' รัฐ | ใช้ฟังก์ชันกับองค์ประกอบที่สอดคล้องกันของสองคอลเลกชันโดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ คอลเล็กชันต้องมีขนาดเท่ากัน หากฟังก์ชันอินพุตคือ f และองค์ประกอบคือ i0 ... iN และ j0 ... jN ฟังก์ชันนี้จะคำนวณ f i0 j0 (... (f iN jN s)) |
forall: ('T → bool) →' T list → bool | ทดสอบว่าองค์ประกอบทั้งหมดของคอลเล็กชันตรงตามเพรดิเคตที่กำหนดหรือไม่ |
forall2: ('T1 →' T2 → bool) → 'รายการ T1 →' รายการ T2 →บูล | ทดสอบว่าองค์ประกอบที่เกี่ยวข้องทั้งหมดของคอลเลกชันตรงตามเพรดิเคตที่กำหนดหรือไม่ |
หัว: 'T list →' T | ส่งคืนองค์ประกอบแรกของรายการ |
init: int → (int → 'T) →' รายการ T | สร้างรายการโดยเรียกตัวสร้างที่กำหนดในแต่ละดัชนี |
isEmpty: 'T list → bool | ผลตอบแทน true หากรายการไม่มีองค์ประกอบ false มิฉะนั้น. |
iter: ('T →หน่วย) →' T รายการ→หน่วย | ใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของคอลเล็กชัน |
iter2: ('T1 →' T2 →หน่วย) → 'รายการ T1 →' รายการ T2 →หน่วย | ใช้ฟังก์ชันที่กำหนดกับสองคอลเลกชันพร้อมกัน คอลเลกชันต้องมีขนาดเท่ากัน |
iteri: (int → 'T →หน่วย) →' T รายการ→หน่วย | ใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของคอลเล็กชัน จำนวนเต็มที่ส่งผ่านไปยังฟังก์ชันบ่งชี้ดัชนีขององค์ประกอบ |
iteri2: (int → 'T1 →' T2 → unit) → 'T1 list →' T2 list → unit | ใช้ฟังก์ชันที่กำหนดกับสองคอลเลกชันพร้อมกัน คอลเลกชันต้องมีขนาดเท่ากัน จำนวนเต็มที่ส่งผ่านไปยังฟังก์ชันบ่งชี้ดัชนีขององค์ประกอบ |
ความยาว: 'T list → int | ส่งกลับความยาวของรายการ |
แผนที่: ('T →' U) → 'T list →' รายการ U | สร้างคอลเล็กชันใหม่ที่มีองค์ประกอบซึ่งเป็นผลลัพธ์ของการใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของคอลเล็กชัน |
map2: ('T1 →' T2 → 'U) →' รายการ T1 → 'รายการ T2 →' รายการ U | สร้างคอลเล็กชันใหม่ที่มีองค์ประกอบเป็นผลลัพธ์ของการใช้ฟังก์ชันที่กำหนดกับองค์ประกอบที่เกี่ยวข้องของทั้งสองคอลเลคชันแบบคู่กัน |
map3: ('T1 →' T2 → 'T3 →' U) → 'รายการ T1 →' รายการ T2 → 'รายการ T3 →' รายการ U | สร้างคอลเลกชันใหม่ที่มีองค์ประกอบเป็นผลมาจากการใช้ฟังก์ชันที่กำหนดกับองค์ประกอบที่เกี่ยวข้องของทั้งสามคอลเลกชันพร้อมกัน |
mapi: (int → 'T →' U) → 'T list →' รายการ U | สร้างคอลเล็กชันใหม่ที่มีองค์ประกอบซึ่งเป็นผลลัพธ์ของการใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของคอลเล็กชัน ดัชนีจำนวนเต็มที่ส่งผ่านไปยังฟังก์ชันบ่งชี้ดัชนี (จาก 0) ขององค์ประกอบที่ถูกเปลี่ยน |
mapi2: (int → 'T1 →' T2 → 'U) →' รายการ T1 → 'รายการ T2 →' รายการ U | เช่นเดียวกับ List.mapi แต่การแมปองค์ประกอบที่เกี่ยวข้องจากสองรายการที่มีความยาวเท่ากัน |
สูงสุด: 'T list →' T | ส่งคืนองค์ประกอบที่ยิ่งใหญ่ที่สุดของรายการทั้งหมดโดยเปรียบเทียบโดยใช้ Operators.max |
maxBy: ('T →' U) → 'T list →' T | ส่งคืนองค์ประกอบที่ยิ่งใหญ่ที่สุดของรายการทั้งหมดโดยเปรียบเทียบโดยใช้ Operators.max กับผลลัพธ์ของฟังก์ชัน |
นาที: 'T list →' T | ส่งคืนค่าต่ำสุดขององค์ประกอบทั้งหมดของรายการเปรียบเทียบโดยใช้ Operators.min |
minBy: ('T →' U) → 'T list →' T | ส่งคืนค่าต่ำสุดขององค์ประกอบทั้งหมดของรายการเปรียบเทียบโดยใช้ Operators.min กับผลลัพธ์ของฟังก์ชัน |
ที่ n: 'T list → int →' T | ดัชนีลงในรายการ องค์ประกอบแรกมีดัชนี 0 |
ofArray: รายการ 'T [] →' T | สร้างรายการจากอาร์เรย์ที่กำหนด |
ofSeq: seq <'T> →' T รายการ | สร้างรายการใหม่จากวัตถุที่ระบุได้ |
พาร์ติชัน: ('T → bool) →รายการ' T * 'T | แยกคอลเลกชันออกเป็นสองคอลเลกชันโดยมีองค์ประกอบที่เพรดิเคตส่งกลับ true และ false ตามลำดับ |
อนุญาต: (int → int) → 'T list →' T list | ส่งคืนรายการที่มีองค์ประกอบทั้งหมดที่ปรับเปลี่ยนตามการเรียงสับเปลี่ยนที่ระบุ |
เลือก: ('T →' ตัวเลือก U) → 'T list →' U | ใช้ฟังก์ชันที่กำหนดกับองค์ประกอบที่ต่อเนื่องส่งคืนผลลัพธ์แรกที่ฟังก์ชันส่งคืน Some เพื่อคุณค่าบางอย่าง |
ลด: ('T →' T → 'T) →' T list → 'T | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของคอลเลกชันโดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ ฟังก์ชันนี้ใช้ฟังก์ชันที่ระบุกับสององค์ประกอบแรกของรายการ จากนั้นจะส่งผลลัพธ์นี้ไปยังฟังก์ชันพร้อมกับองค์ประกอบที่สามและอื่น ๆ สุดท้ายก็ส่งกลับผลลัพธ์สุดท้าย หากฟังก์ชันอินพุตคือ f และองค์ประกอบคือ i0 ... iN ฟังก์ชันนี้จะคำนวณ f (... (f i0 i1) i2 ... ) iN |
ลดกลับ: ('T →' T → 'T) →' T list → 'T | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของคอลเลกชันโดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ หากฟังก์ชันอินพุต isf และองค์ประกอบคือ i0 ... iN ฟังก์ชันนี้จะคำนวณ f i0 (... (f iN-1 iN)) |
ทำซ้ำ: (int → 'T →' T รายการ) | สร้างรายการโดยเรียกตัวสร้างที่กำหนดในแต่ละดัชนี |
rev: รายการ 'T →' T | ส่งคืนรายการใหม่ที่มีองค์ประกอบในลำดับย้อนกลับ |
สแกน: ('State →' T → 'State) →' State → 'T list →' รายการสถานะ | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของคอลเลกชันโดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ ฟังก์ชันนี้รับอาร์กิวเมนต์ที่สองและใช้ฟังก์ชันที่ระบุและองค์ประกอบแรกของรายการ จากนั้นจะส่งผลลัพธ์นี้ไปยังฟังก์ชันพร้อมกับองค์ประกอบที่สองและอื่น ๆ สุดท้ายจะส่งคืนรายการผลลัพธ์ระดับกลางและผลลัพธ์สุดท้าย |
scanBack: ('T →' State → 'State) →' T list → 'State →' รายการสถานะ | เช่นเดียวกับ foldBack แต่ส่งกลับทั้งผลลัพธ์ขั้นกลางและผลลัพธ์สุดท้าย |
เรียงลำดับ: รายการ 'T →' รายการ T | จัดเรียงรายการที่กำหนดโดยใช้ Operators.compare |
sortBy: ('T →' Key) → 'T list →' T list | จัดเรียงรายการที่กำหนดโดยใช้คีย์ที่กำหนดโดยการฉายภาพที่กำหนด คีย์ถูกเปรียบเทียบโดยใช้ Operators.compare |
sortWith: ('T →' T → int) → 'T list →' รายการ T | จัดเรียงรายการที่กำหนดโดยใช้ฟังก์ชันการเปรียบเทียบที่กำหนด |
ผลรวม: ^ T รายการ→ ^ T | ส่งคืนผลรวมขององค์ประกอบในรายการ |
sumBy: ('T → ^ U) →' T list → ^ U | ส่งกลับผลรวมของผลลัพธ์ที่สร้างขึ้นโดยใช้ฟังก์ชันกับแต่ละองค์ประกอบของรายการ |
หาง: รายการ T →รายการ T | ส่งคืนรายการอินพุตที่ไม่มีองค์ประกอบแรก |
toArray: 'T รายการ→' T [] | สร้างอาร์เรย์จากรายการที่กำหนด |
toSeq: 'T list → seq <' T> | ดูรายการที่กำหนดเป็นลำดับ |
tryFind: ('T → bool) →' T list → 'ตัวเลือก T | ส่งคืนองค์ประกอบแรกที่ฟังก์ชันที่กำหนดส่งคืน true. กลับNone หากไม่มีองค์ประกอบดังกล่าว |
tryFindIndex: ('T → bool) →' T list →ตัวเลือก int | ส่งคืนดัชนีขององค์ประกอบแรกในรายการที่ตรงตามเพรดิเคตที่กำหนด กลับNone หากไม่มีองค์ประกอบดังกล่าว |
tryPick: (ตัวเลือก 'T →' U) → 'T list →' ตัวเลือก U | ใช้ฟังก์ชันที่กำหนดกับองค์ประกอบที่ต่อเนื่องส่งคืนผลลัพธ์แรกที่ฟังก์ชันส่งคืน Someเพื่อคุณค่าบางอย่าง หากไม่มีองค์ประกอบดังกล่าวให้ส่งคืนNone. |
เปิดเครื่องรูด: ('T1 *' T2) รายการ→ 'รายการ T1 *' รายการ T2 | แบ่งรายชื่อคู่ออกเป็นสองรายการ |
unzip3: ('T1 *' T2 * 'T3) รายการ→' รายการ T1 * 'รายการ T2 *' รายการ T3 | แบ่งรายชื่อสามรายการออกเป็นสามรายการ |
zip: รายการ 'T1 →' รายการ T2 → ('T1 *' T2) | รวมสองรายการเป็นรายการคู่ ทั้งสองรายการต้องมีความยาวเท่ากัน |
zip3: รายการ 'T1 →' รายการ T2 → 'รายการ T3 → (' T1 * 'T2 *' T3) | รวมสามรายการเป็นรายการสามเท่า รายการต้องมีความยาวเท่ากัน |
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการใช้ฟังก์ชันข้างต้น -
ตัวอย่าง 1
โปรแกรมนี้แสดงการย้อนกลับรายการแบบวนซ้ำ -
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)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
อย่างไรก็ตามคุณสามารถใช้ไฟล์ rev ฟังก์ชั่นของโมดูลเพื่อวัตถุประสงค์เดียวกัน -
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
printfn "The reversed list: %A" (List.rev list1)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
ตัวอย่าง 2
โปรแกรมนี้แสดงการกรองรายการโดยใช้ List.filter วิธีการ -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Filtered list: [2; 4; 6; 8; 10]
ตัวอย่างที่ 3
List.map วิธีการแมปรายการจากประเภทหนึ่งไปยังอีกประเภทหนึ่ง -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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"]
ตัวอย่างที่ 4
List.append method และตัวดำเนินการ @ ต่อท้ายรายการหนึ่งเข้าด้วยกัน -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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']
ตัวอย่างที่ 5
List.sortวิธีการจัดเรียงรายการ List.sum วิธีการให้ผลรวมขององค์ประกอบในรายการและ List.average วิธีการให้ค่าเฉลี่ยขององค์ประกอบในรายการ -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
การดำเนินการ "พับ" ใช้ฟังก์ชันกับแต่ละองค์ประกอบในรายการรวมผลลัพธ์ของฟังก์ชันในตัวแปรตัวสะสมและส่งกลับตัวสะสมซึ่งเป็นผลมาจากการดำเนินการพับ
ตัวอย่างที่ 6
List.fold วิธีใช้ฟังก์ชันกับแต่ละองค์ประกอบจากซ้ายไปขวาในขณะที่ List.foldBack ใช้ฟังก์ชันกับแต่ละองค์ประกอบจากขวาไปซ้าย
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 ])
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.
ลำดับเช่นรายการยังแสดงถึงคอลเล็กชันของค่าที่เรียงลำดับ อย่างไรก็ตามองค์ประกอบในลำดับหรือนิพจน์ลำดับจะถูกคำนวณเมื่อจำเป็น พวกเขาไม่ได้คำนวณพร้อมกันและด้วยเหตุนี้จึงใช้เพื่อแสดงโครงสร้างข้อมูลที่ไม่มีที่สิ้นสุด
การกำหนดลำดับ
ลำดับถูกกำหนดโดยใช้ไวยากรณ์ต่อไปนี้ -
seq { expr }
ตัวอย่างเช่น,
let seq1 = seq { 1 .. 10 }
การสร้างลำดับและนิพจน์ลำดับ
เช่นเดียวกับรายการคุณสามารถสร้างลำดับโดยใช้ช่วงและความเข้าใจ
นิพจน์ลำดับคือนิพจน์ที่คุณสามารถเขียนเพื่อสร้างลำดับ สิ่งเหล่านี้สามารถทำได้ -
- โดยระบุช่วง.
- โดยระบุช่วงด้วยการเพิ่มหรือลด
- โดยใช้ไฟล์ yield คำหลักเพื่อสร้างค่าที่กลายเป็นส่วนหนึ่งของลำดับ
- โดยใช้ตัวดำเนินการ→
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
ตัวอย่าง 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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); ...]
ตัวอย่าง 2
โปรแกรมต่อไปนี้จะพิมพ์จำนวนเฉพาะตั้งแต่ 1 ถึง 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
1
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
การดำเนินการขั้นพื้นฐานเกี่ยวกับลำดับ
ตารางต่อไปนี้แสดงการดำเนินการพื้นฐานเกี่ยวกับชนิดข้อมูลลำดับ -
มูลค่า | คำอธิบาย |
---|---|
ผนวก: seq <'T> → seq <' T> → seq <'T> | รวมการแจงนับที่กำหนดทั้งสองเป็นการแจกแจงแบบเรียงต่อกัน |
ค่าเฉลี่ย: seq <^ T> → ^ T | ส่งคืนค่าเฉลี่ยขององค์ประกอบในลำดับ |
โดยเฉลี่ย: ('T → ^ U) → seq <' T> → ^ U | ส่งกลับค่าเฉลี่ยของผลลัพธ์ที่สร้างขึ้นโดยใช้ฟังก์ชันกับแต่ละองค์ประกอบของลำดับ |
แคช: seq <'T> → seq <' T> | ส่งคืนลำดับที่สอดคล้องกับลำดับอินพุตของเวอร์ชันแคช |
นักแสดง: IEnumerable → seq <'T> | รวมระบบที่พิมพ์แบบหลวม ๆ ลำดับคอลเลกชันเป็นลำดับที่พิมพ์ |
เลือก: ('T →' ตัวเลือก U) → seq <'T> → seq <' U> | ใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของรายการ ส่งคืนรายการที่ประกอบด้วยผลลัพธ์สำหรับแต่ละองค์ประกอบที่ฟังก์ชันส่งคืนSome. |
รวบรวม: ('T →' คอลเลคชัน) → seq <'T> → seq <' U> | ใช้ฟังก์ชันที่กำหนดให้กับแต่ละองค์ประกอบของลำดับและเชื่อมผลลัพธ์ทั้งหมดเข้าด้วยกัน |
เปรียบเทียบกับ: ('T →' T → int) → seq <'T> → seq <' T> → int | เปรียบเทียบสองลำดับโดยใช้ฟังก์ชันการเปรียบเทียบที่กำหนดองค์ประกอบตามองค์ประกอบ |
concat: seq <'Collection> → seq <' T> | รวมการแจงนับที่กำหนดเป็นการแจงนับแบบเรียงต่อกัน |
countBy: ('T →' Key) → seq <'T> → seq <' Key * int> | ใช้ฟังก์ชันสร้างคีย์กับแต่ละองค์ประกอบของลำดับและส่งคืนลำดับที่ให้คีย์ที่ไม่ซ้ำกันและจำนวนครั้งที่เกิดขึ้นในลำดับดั้งเดิม |
ล่าช้า: (หน่วย→ seq <'T>) → seq <' T> | ส่งคืนลำดับที่สร้างขึ้นจากข้อมูลจำเพาะล่าช้าที่กำหนดของลำดับ |
แตกต่าง: seq <'T> → seq <' T> | ส่งคืนลำดับที่ไม่มีรายการที่ซ้ำกันตามการเปรียบเทียบแฮชทั่วไปและการเปรียบเทียบความเท่าเทียมกันในรายการ หากองค์ประกอบเกิดขึ้นหลายครั้งในลำดับเหตุการณ์ที่เกิดขึ้นในภายหลังจะถูกละทิ้ง |
ชัดเจนโดย: ('T →' คีย์) → seq <'T> → seq <' T> | ส่งคืนลำดับที่ไม่มีรายการซ้ำกันตามการเปรียบเทียบแฮชทั่วไปและการเปรียบเทียบความเท่าเทียมกันบนคีย์ที่ส่งคืนโดยฟังก์ชันสร้างคีย์ที่กำหนด หากองค์ประกอบเกิดขึ้นหลายครั้งในลำดับเหตุการณ์ที่เกิดขึ้นในภายหลังจะถูกละทิ้ง |
ว่างเปล่า: seq <'T> | สร้างลำดับว่าง |
ตรงหนึ่ง: seq <'T> →' T | ส่งคืนองค์ประกอบเดียวของลำดับ |
มีอยู่: ('T → bool) → seq <' T> → bool | ทดสอบว่าองค์ประกอบใดของลำดับตรงตามเพรดิเคตที่กำหนดหรือไม่ |
มีอยู่ 2: ('T1 →' T2 →บูล) → seq <'T1> → seq <' T2> →บูล | ทดสอบว่าคู่ขององค์ประกอบที่สอดคล้องกันของลำดับอินพุตตรงตามเพรดิเคตที่กำหนดหรือไม่ |
ตัวกรอง: ('T → bool) → seq <' T> → seq <'T> | ส่งคืนคอลเล็กชันใหม่ที่มีเฉพาะองค์ประกอบของคอลเล็กชันที่เพรดิเคตที่ระบุส่งคืน true. |
ค้นหา: ('T → bool) → seq <' T> → 'T | ส่งคืนองค์ประกอบแรกที่ฟังก์ชันที่กำหนดส่งคืน true. |
findIndex: ('T → bool) → seq <' T> → int | ส่งคืนดัชนีขององค์ประกอบแรกที่ฟังก์ชันที่กำหนดส่งกลับ true. |
พับ: ('State →' T → 'State) →' State → seq <'T> →' State | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของคอลเลกชันโดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ หากฟังก์ชันอินพุตเป็น f และองค์ประกอบคือ i0 ... iN ฟังก์ชันนี้จะคำนวณ f (... (fs i0) ... ) iN |
สำหรับ: ('T → bool) → seq <' T> → bool | ทดสอบว่าองค์ประกอบทั้งหมดของลำดับตรงตามเพรดิเคตที่กำหนดหรือไม่ |
forall2: ('T1 →' T2 →บูล) → seq <'T1> → seq <' T2> →บูล | ทดสอบคู่ขององค์ประกอบทั้งหมดที่ดึงมาจากสองลำดับตรงตามเพรดิเคตที่กำหนด หากลำดับหนึ่งสั้นกว่าอีกลำดับองค์ประกอบที่เหลือของลำดับที่ยาวกว่าจะถูกละเว้น |
groupBy: ('T →' Key) → seq <'T> → seq <' Key * seq <'T >> | ใช้ฟังก์ชันสร้างคีย์กับแต่ละองค์ประกอบของลำดับและให้ลำดับของคีย์ที่ไม่ซ้ำกัน แต่ละคีย์ที่ไม่ซ้ำกันยังมีลำดับขององค์ประกอบทั้งหมดที่ตรงกับคีย์นี้ |
หัว: seq <'T> →' T | ส่งคืนองค์ประกอบแรกของลำดับ |
init: int → (int → 'T) → seq <' T> | สร้างลำดับใหม่ซึ่งเมื่อทำซ้ำจะส่งคืนองค์ประกอบที่ต่อเนื่องกันโดยการเรียกใช้ฟังก์ชันที่กำหนดจนถึงจำนวนที่กำหนด ผลลัพธ์ของการเรียกใช้ฟังก์ชันจะไม่ถูกบันทึกนั่นคือฟังก์ชันจะถูกนำไปใช้ใหม่ตามความจำเป็นเพื่อสร้างองค์ประกอบใหม่ ฟังก์ชันจะถูกส่งผ่านดัชนีของรายการที่สร้างขึ้น |
initInfinite: (int → 'T) → seq <' T> | สร้างลำดับใหม่ซึ่งเมื่อทำซ้ำจะส่งคืนองค์ประกอบต่อเนื่องโดยการเรียกใช้ฟังก์ชันที่กำหนด ผลลัพธ์ของการเรียกใช้ฟังก์ชันจะไม่ถูกบันทึกกล่าวคือฟังก์ชันจะถูกนำไปใช้ใหม่ตามความจำเป็นเพื่อสร้างองค์ประกอบใหม่ ฟังก์ชันจะถูกส่งผ่านดัชนีของรายการที่สร้างขึ้น |
isEmpty: seq <'T> → bool | ทดสอบว่าลำดับมีองค์ประกอบหรือไม่ |
iter: ('T →หน่วย) → seq <' T> →หน่วย | ใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของคอลเล็กชัน |
iter2: ('T1 →' T2 →หน่วย) → seq <'T1> → seq <' T2> →หน่วย | ใช้ฟังก์ชันที่กำหนดกับสองคอลเลกชันพร้อมกัน หากลำดับหนึ่งสั้นกว่าอีกลำดับองค์ประกอบที่เหลือของลำดับที่ยาวกว่าจะถูกละเว้น |
iteri: (int → 'T →หน่วย) → seq <' T> →หน่วย | ใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของคอลเล็กชัน จำนวนเต็มที่ส่งผ่านไปยังฟังก์ชันบ่งชี้ดัชนีขององค์ประกอบ |
สุดท้าย: seq <'T> →' T | ส่งคืนองค์ประกอบสุดท้ายของลำดับ |
ความยาว: seq <'T> → int | ส่งกลับความยาวของลำดับ |
แผนที่: ('T →' U) → seq <'T> → seq <' U> | สร้างคอลเล็กชันใหม่ที่มีองค์ประกอบซึ่งเป็นผลลัพธ์ของการใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของคอลเล็กชัน ฟังก์ชันที่กำหนดจะถูกนำไปใช้เนื่องจากมีการเรียกร้ององค์ประกอบโดยใช้เมธอด MoveNext บนตัวนับที่ดึงมาจากอ็อบเจ็กต์ |
แผนที่ 2: ('T1 →' T2 → 'U) → seq <' T1> → seq <'T2> → seq <' U> | สร้างคอลเล็กชันใหม่ที่มีองค์ประกอบเป็นผลลัพธ์ของการใช้ฟังก์ชันที่กำหนดกับคู่ขององค์ประกอบที่สอดคล้องกันจากสองลำดับ หากลำดับอินพุตหนึ่งสั้นกว่าอีกลำดับองค์ประกอบที่เหลือของลำดับที่ยาวกว่าจะถูกละเว้น |
แผนที่: (int → 'T →' U) → seq <'T> → seq <' U> | สร้างคอลเล็กชันใหม่ที่มีองค์ประกอบซึ่งเป็นผลลัพธ์ของการใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของคอลเล็กชัน ดัชนีจำนวนเต็มที่ส่งผ่านไปยังฟังก์ชันบ่งชี้ดัชนี (จาก 0) ขององค์ประกอบที่ถูกเปลี่ยน |
สูงสุด: seq <'T> →' T | ส่งคืนองค์ประกอบที่ยิ่งใหญ่ที่สุดของลำดับทั้งหมดโดยเปรียบเทียบโดยใช้ Operators.max |
maxBy: ('T →' U) → seq <'T> →' T | ส่งคืนองค์ประกอบที่ยิ่งใหญ่ที่สุดของลำดับทั้งหมดโดยเปรียบเทียบโดยใช้ Operators.max กับผลลัพธ์ของฟังก์ชัน |
นาที: seq <'T> →' T | ส่งคืนค่าต่ำสุดขององค์ประกอบทั้งหมดของลำดับเปรียบเทียบโดยใช้ Operators.min |
นาทีโดย: ('T →' U) → seq <'T> →' T | ส่งคืนค่าต่ำสุดขององค์ประกอบทั้งหมดของลำดับเปรียบเทียบโดยใช้ Operators.min กับผลลัพธ์ของฟังก์ชัน |
ที่ n: int → seq <'T> →' T | คำนวณองค์ประกอบที่nในคอลเลกชัน |
ofArray: 'T array → seq <' T> | ดูอาร์เรย์ที่กำหนดเป็นลำดับ |
ofList: 'T list → seq <' T> | ดูรายการที่กำหนดเป็นลำดับ |
pairwise: seq <'T> → seq <' T * 'T> | ส่งคืนลำดับของแต่ละองค์ประกอบในลำดับการป้อนข้อมูลและลำดับก่อนหน้ายกเว้นองค์ประกอบแรกซึ่งส่งคืนเป็นลำดับก่อนหน้าขององค์ประกอบที่สองเท่านั้น |
เลือก: ('T →' ตัวเลือก U) → seq <'T> →' U | ใช้ฟังก์ชันที่กำหนดกับองค์ประกอบต่อเนื่องโดยส่งคืนค่าแรกโดยที่ฟังก์ชันส่งกลับ a Some มูลค่า. |
อ่านอย่างเดียว: seq <'T> → seq <' T> | สร้างอ็อบเจ็กต์ลำดับใหม่ที่มอบหมายให้กับอ็อบเจ็กต์ลำดับที่กำหนด สิ่งนี้ทำให้แน่ใจว่าลำดับดั้งเดิมจะไม่สามารถค้นพบและกลายพันธุ์โดยการร่ายประเภทได้ ตัวอย่างเช่นหากกำหนดอาร์เรย์ลำดับที่ส่งคืนจะส่งคืนองค์ประกอบของอาร์เรย์ แต่คุณไม่สามารถส่งออบเจ็กต์ลำดับที่ส่งคืนไปยังอาร์เรย์ได้ |
ลด: ('T →' T → 'T) → seq <' T> → 'T | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของลำดับเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ เริ่มต้นด้วยการใช้ฟังก์ชันกับสององค์ประกอบแรก จากนั้นป้อนผลลัพธ์นี้ลงในฟังก์ชันพร้อมกับองค์ประกอบที่สามและอื่น ๆ ส่งคืนผลลัพธ์สุดท้าย |
สแกน: ('State →' T → 'State) →' State → seq <'T> → seq <' State> | เช่นเดียวกับ Seq.fold แต่คำนวณตามคำขอและส่งกลับลำดับของตัวกลางและผลลัพธ์สุดท้าย |
ซิงเกิลตัน: 'T → seq <' T> | ส่งคืนลำดับที่ให้ผลลัพธ์หนึ่งรายการเท่านั้น |
ข้าม: int → seq <'T> → seq <' T> | ส่งคืนลำดับที่ข้ามจำนวนองค์ประกอบที่ระบุของลำดับพื้นฐานจากนั้นให้องค์ประกอบที่เหลือของลำดับ |
skipWhile: ('T → bool) → seq <' T> → seq <'T> | ส่งคืนลำดับที่เมื่อทำซ้ำจะข้ามองค์ประกอบของลำดับพื้นฐานในขณะที่เพรดิเคตที่ระบุจะส่งกลับ true, จากนั้นให้องค์ประกอบที่เหลือของลำดับ |
เรียงลำดับ: seq <'T> → seq <' T> | ให้ลำดับที่เรียงตามคีย์ |
sortBy: ('T →' Key) → seq <'T> → seq <' T> | ใช้ฟังก์ชันสร้างคีย์กับแต่ละองค์ประกอบของลำดับและให้ลำดับที่เรียงตามคีย์ คีย์จะถูกเปรียบเทียบโดยใช้การเปรียบเทียบทั่วไปที่ดำเนินการโดย Operators.compare |
ผลรวม: seq <^ T> → ^ T | ส่งคืนผลรวมขององค์ประกอบในลำดับ |
sumBy | ส่งกลับผลรวมของผลลัพธ์ที่สร้างขึ้นโดยใช้ฟังก์ชันกับแต่ละองค์ประกอบของลำดับ |
ใช้เวลา: int → seq <'T> → seq <' T> | ส่งคืนองค์ประกอบแรกของลำดับจนถึงจำนวนที่ระบุ |
takeWhile: ('T → bool) → seq <' T> → seq <'T> | ส่งคืนลำดับที่เมื่อทำซ้ำจะให้องค์ประกอบของลำดับพื้นฐานในขณะที่เพรดิเคตที่ระบุจะส่งกลับ true, จากนั้นไม่ส่งคืนองค์ประกอบเพิ่มเติม |
toArray: seq <'T> →' T [] | สร้างอาร์เรย์จากคอลเล็กชันที่กำหนด |
toList: seq <'T> →' T รายการ | สร้างรายการจากคอลเลกชันที่กำหนด |
ตัดทอน: int → seq <'T> → seq <' T> | ส่งคืนลำดับที่เมื่อแจงนับส่งคืนองค์ประกอบไม่เกินจำนวนที่ระบุ |
tryFind: ('T → bool) →ตัวเลือก seq <' T> → 'T | ส่งคืนองค์ประกอบแรกที่ฟังก์ชันที่กำหนดส่งคืน true, หรือ None หากไม่มีองค์ประกอบดังกล่าว |
tryFindIndex: ('T → bool) → seq <' T> →ตัวเลือก int | ส่งคืนดัชนีขององค์ประกอบแรกในลำดับที่ตรงตามเพรดิเคตที่กำหนดหรือ None หากไม่มีองค์ประกอบดังกล่าว |
tryPick: (ตัวเลือก 'T →' U) → seq <'T> →' ตัวเลือก U | ใช้ฟังก์ชันที่กำหนดกับองค์ประกอบต่อเนื่องโดยส่งคืนค่าแรกโดยที่ฟังก์ชันส่งกลับ a Some มูลค่า. |
แฉ: (ตัวเลือก 'รัฐ→' T * ') →' รัฐ→ seq <'T> | ส่งคืนลำดับที่มีองค์ประกอบที่สร้างโดยการคำนวณที่กำหนด |
โดยที่: ('T → bool) → seq <' T> → seq <'T> | ส่งคืนคอลเล็กชันใหม่ที่มีเฉพาะองค์ประกอบของคอลเล็กชันที่เพรดิเคตที่ระบุส่งคืน true. คำพ้องความหมายสำหรับ Seq.filter |
windowed: int → seq <'T> → seq <' T []> | ส่งคืนลำดับที่ให้หน้าต่างบานเลื่อนขององค์ประกอบที่มีที่ดึงมาจากลำดับอินพุต แต่ละหน้าต่างจะถูกส่งกลับเป็นอาร์เรย์ใหม่ |
zip: seq <'T1> → seq <' T2> → seq <'T1 *' T2> | รวมสองลำดับเป็นรายการคู่ ลำดับทั้งสองไม่จำเป็นต้องมีความยาวเท่ากัน - เมื่อลำดับหนึ่งหมดองค์ประกอบที่เหลือในลำดับอื่นจะถูกละเว้น |
zip3: seq <'T1> → seq <' T2> → seq <'T3> → seq <' T1 * 'T2 *' T3> | รวมสามลำดับไว้ในรายการสามเท่า ลำดับไม่จำเป็นต้องมีความยาวเท่ากัน - เมื่อลำดับหนึ่งหมดองค์ประกอบที่เหลือในลำดับอื่น ๆ จะถูกละเว้น |
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการใช้ฟังก์ชันข้างต้น -
ตัวอย่าง 1
โปรแกรมนี้สร้างลำดับว่างและเติมในภายหลัง -
(* 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""
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
โปรดทราบว่า -
เมธอด Seq.empty สร้างลำดับว่าง
วิธี Seq.singleton สร้างลำดับขององค์ประกอบที่ระบุเพียงรายการเดียว
เมธอด Seq.init สร้างลำดับที่องค์ประกอบถูกสร้างขึ้นโดยใช้ฟังก์ชันที่กำหนด
เมธอด Seq.ofArray และ Seq.ofList <'T> สร้างลำดับจากอาร์เรย์และรายการ
วิธีการ Seq.iter อนุญาตให้วนซ้ำตามลำดับ
ตัวอย่าง 2
เมธอด Seq.unfold สร้างลำดับจากฟังก์ชันการคำนวณที่รับสถานะและแปลงเพื่อสร้างแต่ละองค์ประกอบที่ตามมาในลำดับ
ฟังก์ชันต่อไปนี้จะสร้างจำนวนธรรมชาติ 20 ตัวแรก -
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" "
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
ตัวอย่างที่ 3
เมธอด Seq.truncate สร้างลำดับจากลำดับอื่น แต่ จำกัด ลำดับไว้ที่จำนวนองค์ประกอบที่ระบุ
เมธอด Seq.take สร้างลำดับใหม่ที่มีจำนวนองค์ประกอบที่ระบุจากจุดเริ่มต้นของลำดับ
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""
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
ชุดใน F # คือโครงสร้างข้อมูลที่ทำหน้าที่รวบรวมรายการโดยไม่รักษาลำดับที่จะแทรกรายการ ชุดไม่อนุญาตให้แทรกรายการที่ซ้ำกันในคอลเลกชัน
การสร้างชุด
สามารถสร้างชุดได้ด้วยวิธีต่อไปนี้ -
- โดยการสร้างชุดว่างโดยใช้ Set.empty และเพิ่มรายการโดยใช้ฟังก์ชันเพิ่ม
- การแปลงลำดับและรายการเป็นชุด
โปรแกรมต่อไปนี้แสดงให้เห็นถึงเทคนิค -
(* 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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]
การใช้งานพื้นฐานในชุด
ตารางต่อไปนี้แสดงการดำเนินการพื้นฐานในชุด -
มูลค่า | คำอธิบาย |
---|---|
เพิ่ม: 'T → Set <' T> → Set <'T> | ส่งคืนชุดใหม่ที่มีองค์ประกอบที่เพิ่มเข้ามาในชุด จะไม่มีการเพิ่มข้อยกเว้นหากชุดนั้นมีองค์ประกอบที่กำหนดอยู่แล้ว |
ประกอบด้วย: 'T → Set <' T> → bool | ประเมินเป็น true หากองค์ประกอบที่กำหนดอยู่ในชุดที่กำหนด |
นับ: ตั้งค่า <'T> → int | ส่งคืนจำนวนองค์ประกอบในชุด |
ความแตกต่าง: ตั้งค่า <'T> →ตั้ง <' T> →ตั้งค่า <'T> | ส่งคืนชุดใหม่โดยนำองค์ประกอบของชุดที่สองออกจากชุดแรก |
ว่างเปล่า: ตั้งค่า <'T> | ชุดว่างสำหรับชนิดที่ระบุ |
มีอยู่: ('T → bool) →ตั้งค่า <' T> → bool | ทดสอบว่าองค์ประกอบใดของคอลเล็กชันตรงตามเพรดิเคตที่กำหนด หากฟังก์ชันอินพุตเป็นเพรดิเคตและอิลิเมนต์คือ i0 ... iN ฟังก์ชันนี้จะคำนวณเพรดิเคต i0 หรือ ... หรือเพรดิเคต iN |
ฟิลเตอร์: ('T → bool) → Set <' T> → Set <'T> | ส่งคืนคอลเล็กชันใหม่ที่มีเฉพาะองค์ประกอบของคอลเล็กชันที่เพรดิเคตที่ระบุส่งคืน true. |
พับ: ('State →' T → 'State) →' State → Set <'T> →' State | ใช้ฟังก์ชันการสะสมที่กำหนดกับองค์ประกอบทั้งหมดของเซต |
foldBack: ('T →' State → 'State) →ตั้งค่า <' T> → 'State →' State | ใช้ฟังก์ชันการสะสมที่กำหนดกับองค์ประกอบทั้งหมดของเซต |
สำหรับ: ('T →บูล) →ตั้งค่า <' T> →บูล | ทดสอบว่าองค์ประกอบทั้งหมดของคอลเล็กชันตรงตามเพรดิเคตที่กำหนดหรือไม่ ถ้าฟังก์ชันอินพุตคือ p และองค์ประกอบคือ i0 ... iN ฟังก์ชันนี้จะคำนวณ p i0 && ... && p iN |
ตัดกัน: ตั้งค่า <'T> →ตั้ง <' T> →ตั้งค่า <'T> | คำนวณจุดตัดของทั้งสองชุด |
intersectMany: seq <Set <'T >> → Set <' T> | คำนวณการตัดกันของลำดับชุด ลำดับต้องไม่ว่างเปล่า |
isEmpty: ตั้งค่า <'T> → bool | ผลตอบแทน true หากชุดว่างเปล่า |
isProperSubset: ตั้งค่า <'T> →ตั้งค่า <' T> →บูล | ประเมินเป็น true หากองค์ประกอบทั้งหมดของชุดแรกอยู่ในชุดที่สองและอย่างน้อยหนึ่งองค์ประกอบของชุดที่สองไม่ได้อยู่ในชุดแรก |
isProperSuperset: ตั้งค่า <'T> →ตั้งค่า <' T> →บูล | ประเมินเป็น true หากองค์ประกอบทั้งหมดของชุดที่สองอยู่ในชุดแรกและอย่างน้อยหนึ่งองค์ประกอบของชุดแรกไม่ได้อยู่ในชุดที่สอง |
isSubset: ตั้งค่า <'T> →ตั้งค่า <' T> →บูล | ประเมินเป็น true หากองค์ประกอบทั้งหมดของชุดแรกอยู่ในชุดที่สอง |
isSuperset: ตั้งค่า <'T> →ตั้งค่า <' T> →บูล | ประเมินเป็น true หากองค์ประกอบทั้งหมดของชุดที่สองอยู่ในชุดแรก |
iter: ('T →หน่วย) →ตั้งค่า <' T> →หน่วย | ใช้ฟังก์ชันที่กำหนดให้กับแต่ละองค์ประกอบของชุดโดยเรียงตามฟังก์ชันการเปรียบเทียบ |
แผนที่: ('T →' U) → Set <'T> → Set <' U> | ส่งคืนคอลเล็กชันใหม่ที่มีผลลัพธ์ของการใช้ฟังก์ชันที่กำหนดกับแต่ละองค์ประกอบของชุดอินพุต |
maxElement: ตั้งค่า <'T> →' T | ส่งคืนองค์ประกอบสูงสุดในชุดตามลำดับที่ใช้สำหรับชุด |
minElement: ตั้งค่า <'T> →' T | ส่งคืนองค์ประกอบต่ำสุดในชุดตามลำดับที่ใช้สำหรับชุด |
ofArray: 'T array →ตั้งค่า <' T> | สร้างชุดที่มีองค์ประกอบเดียวกันกับอาร์เรย์ที่กำหนด |
ofList: รายการ T →ตั้งค่า <'T> | สร้างชุดที่มีองค์ประกอบเดียวกันกับรายการที่กำหนด |
ofSeq: seq <'T> →ตั้งค่า <' T> | สร้างคอลเลกชันใหม่จากวัตถุที่ระบุได้ |
พาร์ติชัน: ('T → bool) → Set <' T> → Set <'T> * Set <' T> | แยกชุดออกเป็นสองชุดที่มีองค์ประกอบซึ่งเพรดิเคตที่ระบุส่งกลับค่าจริงและเท็จตามลำดับ |
ลบ: 'T → Set <' T> → Set <'T> | ส่งคืนชุดใหม่โดยนำองค์ประกอบที่ระบุออก จะไม่มีการเพิ่มข้อยกเว้นหากชุดนั้นไม่มีองค์ประกอบที่กำหนด |
ซิงเกิลตัน: 'T → Set <' T> | ชุดที่มีองค์ประกอบที่กำหนด |
toArray: ตั้งค่าอาร์เรย์ <'T> →' T | สร้างอาร์เรย์ที่มีองค์ประกอบของชุดตามลำดับ |
toList: ตั้งค่า <'T> →' T list | สร้างรายการที่มีองค์ประกอบของชุดตามลำดับ |
toSeq: ตั้งค่า <'T> → seq <' T> | ส่งคืนมุมมองที่เรียงลำดับของคอลเลกชันเป็นวัตถุที่แจกแจงได้ |
สหภาพ: ตั้งค่า <'T> →ตั้ง <' T> →ตั้งค่า <'T> | คำนวณการรวมกันของทั้งสองชุด |
unionMany: seq <Set <'T >> → Set <' T> | คำนวณการรวมกันของลำดับชุด |
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการใช้ฟังก์ชันข้างต้น -
ตัวอย่าง
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""
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
ใน F # แผนที่คือชุดชนิดพิเศษที่เชื่อมโยงค่ากับคีย์ แผนที่ถูกสร้างขึ้นในลักษณะเดียวกับที่สร้างชุด
การสร้างแผนที่
แผนที่ถูกสร้างขึ้นโดยการสร้างแผนที่ว่างโดยใช้ Map.empty และเพิ่มรายการโดยใช้ฟังก์ชันเพิ่ม ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
ตัวอย่าง
(* 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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")]
คุณสามารถเข้าถึงแต่ละองค์ประกอบในแผนที่โดยใช้คีย์
ตัวอย่าง
(* 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"]
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Map - students: map
[("Gillian Megan", "1504"); ("Rishita Gupta", "1502"); ("Robin Sahoo", "1503
");
("Zara Ali", "1501")]
"1501"
การใช้งานพื้นฐานบนแผนที่
เพิ่มชื่อโมดูล
ตารางต่อไปนี้แสดงการทำงานพื้นฐานบนแผนที่ -
สมาชิก | คำอธิบาย |
---|---|
เพิ่ม | ส่งคืนแผนที่ใหม่พร้อมกับเพิ่มการเชื่อมโยงไปยังแผนที่ที่กำหนด |
ประกอบด้วยคีย์ | ทดสอบว่าองค์ประกอบอยู่ในโดเมนของแผนที่หรือไม่ |
นับ | จำนวนการผูกในแผนที่ |
มันว่างเปล่า | ส่งคืนค่าจริงหากไม่มีการเชื่อมโยงในแผนที่ |
สิ่งของ | ค้นหาองค์ประกอบในแผนที่ เพิ่ม KeyNotFoundException หากไม่มีการเชื่อมโยงอยู่ในแผนที่ |
ลบ | ลบองค์ประกอบออกจากโดเมนของแผนที่ จะไม่มีการเพิ่มข้อยกเว้นหากไม่มีองค์ประกอบ |
TryFind | ค้นหาองค์ประกอบในแผนที่โดยส่งคืนไฟล์ Some ค่าหากองค์ประกอบอยู่ในโดเมนของแผนที่และ None ถ้าไม่. |
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการใช้ฟังก์ชันข้างต้น -
ตัวอย่าง
(* 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."
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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.
สหภาพแรงงานหรือสหภาพแรงงานที่เลือกปฏิบัติช่วยให้คุณสร้างโครงสร้างข้อมูลที่ซับซ้อนซึ่งแสดงถึงชุดตัวเลือกที่กำหนดไว้อย่างดี ตัวอย่างเช่นคุณต้องสร้างการใช้งานตัวแปรตัวเลือกซึ่งมีสองค่าใช่และไม่ใช่ การใช้เครื่องมือ Unions คุณสามารถออกแบบสิ่งนี้ได้
ไวยากรณ์
การแบ่งแยกสหภาพแรงงานถูกกำหนดโดยใช้ไวยากรณ์ต่อไปนี้ -
type type-name =
| case-identifier1 [of [ fieldname1 : ] type1 [ * [ fieldname2 : ]
type2 ...]
| case-identifier2 [of [fieldname3 : ]type3 [ * [ fieldname4 : ]type4 ...]
...
การใช้งานทางเลือกที่เรียบง่ายของเราจะมีลักษณะดังต่อไปนี้ -
type choice =
| Yes
| No
ตัวอย่างต่อไปนี้ใช้ตัวเลือกประเภท -
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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
x: Yes
y: No
ตัวอย่าง 1
ตัวอย่างต่อไปนี้แสดงการใช้สถานะแรงดันไฟฟ้าที่ตั้งค่าสูงหรือต่ำ -
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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Switch on state: High
Switch off state: Low
Toggle off: High
Toggle the Changed state: Low
ตัวอย่าง 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)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
ตัวแปรใน F # คือ immutable,ซึ่งหมายความว่าเมื่อตัวแปรถูกผูกไว้กับค่าแล้วจะไม่สามารถเปลี่ยนแปลงได้ ซึ่งจริง ๆ แล้วคอมไพล์เป็นคุณสมบัติอ่านอย่างเดียวคง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้
ตัวอย่าง
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะแสดงข้อความแสดงข้อผิดพลาดต่อไปนี้ -
Duplicate definition of value 'x'
Duplicate definition of value 'Y'
Duplicate definition of value 'Z'
ตัวแปรที่ไม่แน่นอน
บางครั้งคุณต้องเปลี่ยนค่าที่เก็บไว้ในตัวแปร เพื่อระบุว่าอาจมีการเปลี่ยนแปลงในค่าของตัวแปรที่ประกาศและกำหนดในส่วนต่อมาของโปรแกรม F # ให้mutableคำสำคัญ. คุณสามารถประกาศและกำหนดตัวแปรที่เปลี่ยนแปลงได้โดยใช้คีย์เวิร์ดนี้ซึ่งค่าที่คุณจะเปลี่ยนไป
mutable คำสำคัญช่วยให้คุณสามารถประกาศและกำหนดค่าในตัวแปรที่เปลี่ยนแปลงได้
คุณสามารถกำหนดค่าเริ่มต้นให้กับตัวแปรที่เปลี่ยนแปลงได้โดยใช้ letคำสำคัญ. อย่างไรก็ตามในการกำหนดค่าใหม่ที่ตามมาคุณต้องใช้ไฟล์<- ตัวดำเนินการ
ตัวอย่างเช่น,
let mutable x = 10
x <- 15
ตัวอย่างต่อไปนี้จะล้างแนวคิด -
ตัวอย่าง
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
การใช้ข้อมูลที่ไม่แน่นอน
ข้อมูลที่เปลี่ยนแปลงได้มักจำเป็นและใช้ในการประมวลผลข้อมูลโดยเฉพาะอย่างยิ่งกับโครงสร้างข้อมูลบันทึก ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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";}
อาร์เรย์เป็นคอลเลกชันที่มีขนาดคงที่ฐานเป็นศูนย์และไม่สามารถเปลี่ยนแปลงได้ขององค์ประกอบข้อมูลที่ต่อเนื่องกันซึ่งเป็นชนิดเดียวกันทั้งหมด
การสร้างอาร์เรย์
คุณสามารถสร้างอาร์เรย์โดยใช้ไวยากรณ์และวิธีการต่างๆหรือโดยใช้ฟังก์ชันจากโมดูลอาร์เรย์ ในส่วนนี้เราจะพูดถึงการสร้างอาร์เรย์โดยไม่ใช้ฟังก์ชันโมดูล
มีสามวิธีในการสร้างอาร์เรย์โดยไม่ใช้ฟังก์ชันเชิงไวยากรณ์ -
- โดยแสดงรายการค่าที่ต่อเนื่องกันระหว่าง [| และ |] และคั่นด้วยอัฒภาค
- โดยการวางแต่ละองค์ประกอบในบรรทัดแยกกันซึ่งในกรณีนี้ตัวคั่นอัฒภาคเป็นทางเลือก
- โดยใช้นิพจน์ลำดับ.
คุณสามารถเข้าถึงองค์ประกอบอาร์เรย์ได้โดยใช้ตัวดำเนินการจุด (.) และวงเล็บ ([และ])
ตัวอย่างต่อไปนี้สาธิตการสร้างอาร์เรย์ -
//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" "
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
1 2 3 4 5 6
1 2 3 4 5
1 4 9 16 25 36 49 64 81 100
การทำงานพื้นฐานบนอาร์เรย์
โมดูลไลบรารี Microsoft.FSharp.Collections.Array สนับสนุนการดำเนินการกับอาร์เรย์หนึ่งมิติ
ตารางต่อไปนี้แสดงการทำงานพื้นฐานบน Arrays -
มูลค่า | คำอธิบาย |
---|---|
ต่อท้าย: 'T [] →' T [] → 'T [] | สร้างอาร์เรย์ที่มีองค์ประกอบของอาร์เรย์หนึ่งตามด้วยองค์ประกอบของอาร์เรย์อื่น |
ค่าเฉลี่ย: ^ T [] → ^ T | ส่งคืนค่าเฉลี่ยขององค์ประกอบในอาร์เรย์ |
โดยเฉลี่ย: ('T → ^ U) →' T [] → ^ U | ส่งกลับค่าเฉลี่ยขององค์ประกอบที่สร้างขึ้นโดยใช้ฟังก์ชันกับแต่ละองค์ประกอบของอาร์เรย์ |
blit: 'T [] → int →' T [] → int → int →หน่วย | อ่านช่วงขององค์ประกอบจากอาร์เรย์หนึ่งและเขียนลงในอีกอาร์เรย์ |
เลือก: (ตัวเลือก 'T → U) →' T [] → 'U [] | ใช้ฟังก์ชันที่ให้มากับแต่ละองค์ประกอบของอาร์เรย์ ส่งคืนอาร์เรย์ที่มีผลลัพธ์ x สำหรับแต่ละองค์ประกอบที่ฟังก์ชันส่งคืนค่า Some (x) |
รวบรวม: ('T →' U []) → T [] → 'U [] | ใช้ฟังก์ชันที่ให้มากับแต่ละองค์ประกอบของอาร์เรย์เชื่อมต่อผลลัพธ์และส่งคืนอาร์เรย์รวม |
concat: seq <'T []> →' T [] | สร้างอาร์เรย์ที่มีองค์ประกอบของแต่ละลำดับของอาร์เรย์ที่ให้มา |
สำเนา: 'T →' T [] | สร้างอาร์เรย์ที่มีองค์ประกอบของอาร์เรย์ที่ให้มา |
สร้าง: int → 'T →' T [] | สร้างอาร์เรย์ที่องค์ประกอบทั้งหมดเป็นค่าที่ระบุในตอนแรก |
ว่างเปล่า: 'T [] | ส่งคืนอาร์เรย์ว่างของประเภทที่กำหนด |
มีอยู่: ('T → bool) →' T [] → bool | ทดสอบว่าองค์ประกอบของอาร์เรย์ตรงตามเพรดิเคตที่ให้มาหรือไม่ |
มีอยู่ 2: ('T1 →' T2 →บูล) → 'T1 [] →' T2 [] →บูล | ทดสอบว่าคู่ขององค์ประกอบที่สอดคล้องกันของสองอาร์เรย์เป็นไปตามเงื่อนไขที่ให้มาหรือไม่ |
เติม: 'T [] → int → int →' T →หน่วย | เติมช่วงขององค์ประกอบของอาร์เรย์ด้วยค่าที่ให้มา |
ตัวกรอง: ('T → bool) →' T [] → 'T [] | ส่งคืนคอลเล็กชันที่มีเฉพาะองค์ประกอบของอาร์เรย์ที่ให้มาซึ่งเงื่อนไขที่ให้มาจะส่งกลับ true. |
ค้นหา: ('T → bool) →' T [] → 'T | ส่งคืนองค์ประกอบแรกที่ฟังก์ชันที่ให้มาส่งกลับ true. เพิ่ม KeyNotFoundException หากไม่มีองค์ประกอบดังกล่าว |
findIndex: ('T → bool) →' T [] → int | ส่งคืนดัชนีขององค์ประกอบแรกในอาร์เรย์ที่ตรงตามเงื่อนไขที่ระบุ เพิ่ม KeyNotFoundException หากไม่มีองค์ประกอบใดที่ตรงตามเงื่อนไข |
พับ: ('รัฐ→' T → 'รัฐ) →' รัฐ→ 'T [] →' รัฐ | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของอาร์เรย์โดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ ถ้าฟังก์ชันอินพุตคือ f และองค์ประกอบอาร์เรย์คือ i0 ... iN ฟังก์ชันนี้จะคำนวณ f (... (fs i0) ... ) iN |
fold2: ('รัฐ→' T1 → 'T2 →' รัฐ) → 'รัฐ→' T1 [] → 'T2 [] →' รัฐ | ใช้ฟังก์ชันกับคู่ขององค์ประกอบจากอาร์เรย์ที่ให้มาสองอาร์เรย์ซ้ายไปขวาเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ อาร์เรย์อินพุตทั้งสองต้องมีความยาวเท่ากัน มิฉะนั้น ArgumentException จะถูกยกขึ้น |
foldBack: ('T →' State → 'State) →' T [] → 'State →' State | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของอาร์เรย์โดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ ถ้าฟังก์ชันอินพุตคือ f และองค์ประกอบอาร์เรย์คือ i0 ... iN ฟังก์ชันนี้จะคำนวณ f i0 (... (f iN s)) |
foldBack2: ('T1 →' T2 → 'รัฐ→' รัฐ) → 'T1 [] →' T2 [] → 'รัฐ→' รัฐ | ใช้ฟังก์ชันกับคู่ขององค์ประกอบจากอาร์เรย์ที่ให้มาสองอาร์เรย์จากขวาไปซ้ายโดยทำเกลียวอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ อาร์เรย์อินพุตทั้งสองต้องมีความยาวเท่ากัน มิฉะนั้น ArgumentException จะถูกยกขึ้น |
สำหรับ: ('T → bool) →' T [] → bool | ทดสอบว่าองค์ประกอบทั้งหมดของอาร์เรย์เป็นไปตามเงื่อนไขที่ให้มาหรือไม่ |
forall2: ('T1 →' T2 →บูล) → 'T1 [] →' T2 [] →บูล | ทดสอบว่าองค์ประกอบที่เกี่ยวข้องทั้งหมดของสองอาร์เรย์ที่ให้มาเป็นไปตามเงื่อนไขที่ระบุหรือไม่ |
รับ: 'T [] → int →' T | รับองค์ประกอบจากอาร์เรย์ |
เริ่ม: int → (int → 'T) →' T [] | ใช้ฟังก์ชันที่ให้มาเพื่อสร้างอาร์เรย์ของมิติข้อมูลที่ให้มา |
isEmpty: 'T [] →บูล | ทดสอบว่าอาร์เรย์มีองค์ประกอบหรือไม่ |
iter: ('T →หน่วย) →' T [] →หน่วย | ใช้ฟังก์ชันที่ให้มากับแต่ละองค์ประกอบของอาร์เรย์ |
iter2: ('T1 →' T2 →หน่วย) → 'T1 [] →' T2 [] →หน่วย) | ใช้ฟังก์ชันที่ให้มากับคู่ขององค์ประกอบจากดัชนีที่ตรงกันในสองอาร์เรย์ อาร์เรย์ทั้งสองต้องมีความยาวเท่ากัน มิฉะนั้น ArgumentException จะถูกยกขึ้น |
iteri: (int → 'T →หน่วย) →' T [] →หน่วย | ใช้ฟังก์ชันที่ให้มากับแต่ละองค์ประกอบของอาร์เรย์ จำนวนเต็มที่ส่งผ่านไปยังฟังก์ชันบ่งชี้ดัชนีขององค์ประกอบ |
iteri2: (int → 'T1 →' T2 → unit) → 'T1 [] →' T2 [] →หน่วย | ใช้ฟังก์ชันที่ให้มากับคู่ขององค์ประกอบจากดัชนีที่ตรงกันในสองอาร์เรย์และส่งผ่านดัชนีขององค์ประกอบด้วย อาร์เรย์ทั้งสองต้องมีความยาวเท่ากัน มิฉะนั้น ArgumentException จะถูกยกขึ้น |
ความยาว: 'T [] → int | ส่งกลับความยาวของอาร์เรย์ คุณสมบัติ Length ทำสิ่งเดียวกัน |
แผนที่: ('T →' U) → 'T [] →' U [] | สร้างอาร์เรย์ที่มีองค์ประกอบเป็นผลลัพธ์ของการใช้ฟังก์ชันที่ให้มากับแต่ละองค์ประกอบของอาร์เรย์ที่ให้มา |
แผนที่ 2: ('T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] | สร้างอาร์เรย์ที่มีองค์ประกอบเป็นผลลัพธ์ของการใช้ฟังก์ชันที่ให้มากับองค์ประกอบที่สอดคล้องกันของอาร์เรย์ที่ให้มาสองอาร์เรย์ อาร์เรย์อินพุตทั้งสองต้องมีความยาวเท่ากัน มิฉะนั้น ArgumentException จะถูกยกขึ้น |
แผนที่: (int → 'T →' U) → 'T [] →' U [] | สร้างอาร์เรย์ที่มีองค์ประกอบเป็นผลลัพธ์ของการใช้ฟังก์ชันที่ให้มากับแต่ละองค์ประกอบของอาร์เรย์ที่ให้มา ดัชนีจำนวนเต็มที่ส่งไปยังฟังก์ชันบ่งชี้ดัชนีขององค์ประกอบที่กำลังเปลี่ยนรูป |
mapi2: (int → 'T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] | สร้างอาร์เรย์ที่มีองค์ประกอบเป็นผลลัพธ์ของการใช้ฟังก์ชันที่ให้มากับองค์ประกอบที่เกี่ยวข้องของทั้งสองคอลเลกชันแบบคู่และส่งผ่านดัชนีขององค์ประกอบ อาร์เรย์อินพุตทั้งสองต้องมีความยาวเท่ากัน มิฉะนั้น ArgumentException จะถูกยกขึ้น |
สูงสุด: 'T [] →' T | ส่งคืนองค์ประกอบที่ใหญ่ที่สุดของอาร์เรย์ทั้งหมด Operators.max ใช้เพื่อเปรียบเทียบองค์ประกอบ |
maxBy: ('T →' U) → 'T [] →' T | ส่งคืนองค์ประกอบที่ใหญ่ที่สุดของอาร์เรย์ทั้งหมดโดยเปรียบเทียบผ่าน Operators.max ในผลลัพธ์ของฟังก์ชัน |
นาที: ('T [] →' T | ส่งคืนองค์ประกอบที่เล็กที่สุดของอาร์เรย์ทั้งหมด Operators.min ใช้เพื่อเปรียบเทียบองค์ประกอบ |
นาทีโดย: ('T →' U) → 'T [] →' T | ส่งคืนองค์ประกอบที่เล็กที่สุดของอาร์เรย์ทั้งหมด Operators.min ใช้เพื่อเปรียบเทียบองค์ประกอบ |
ofList: 'T list →' T [] | สร้างอาร์เรย์จากรายการที่ให้มา |
ofSeq: seq <'T> →' T [] | สร้างอาร์เรย์จากอ็อบเจ็กต์ที่แจกแจงที่ให้มา |
พาร์ติชัน: ('T → bool) →' T [] → 'T [] *' T [] | แบ่งอาร์เรย์ออกเป็นสองอาร์เรย์โดยหนึ่งมีองค์ประกอบที่เงื่อนไขที่ให้มาส่งกลับ true, และอื่น ๆ ที่มีสิ่งที่ส่งคืน false. |
อนุญาต: (int → int) → 'T [] →' T [] | อนุญาตองค์ประกอบของอาร์เรย์ตามการเปลี่ยนแปลงที่ระบุ |
เลือก: ('T →' ตัวเลือก U) → 'T [] →' U | ใช้ฟังก์ชันที่ให้มากับองค์ประกอบต่อเนื่องของอาร์เรย์ที่ให้มาโดยส่งคืนผลลัพธ์แรกโดยที่ฟังก์ชันส่งคืนค่า Some (x) สำหรับบาง x ถ้าฟังก์ชันไม่คืนค่า Some (x) KeyNotFoundException จะถูกยกขึ้น |
ลด: ('T →' T → 'T) →' T [] → 'T | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของอาร์เรย์โดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ ถ้าฟังก์ชันอินพุตคือ f และองค์ประกอบอาร์เรย์คือ i0 ... iN ฟังก์ชันนี้จะคำนวณ f (... (f i0 i1) ... ) iN ถ้าอาร์เรย์มีขนาดเป็นศูนย์ ArgumentException จะถูกยกขึ้น |
ลดกลับ: ('T →' T → 'T) →' T [] → 'T | ใช้ฟังก์ชันกับแต่ละองค์ประกอบของอาร์เรย์โดยทำเธรดอาร์กิวเมนต์ตัวสะสมผ่านการคำนวณ หากฟังก์ชันอินพุตเป็น f และองค์ประกอบคือ i0 ... iN ฟังก์ชันนี้จะคำนวณ f i0 (... (f iN-1 iN)) ถ้าอาร์เรย์มีขนาดเป็นศูนย์ ArgumentException จะถูกยกขึ้น |
rev: 'T [] →' T [] | กลับลำดับขององค์ประกอบในอาร์เรย์ที่ให้มา |
สแกน: ('State →' T → 'State) →' State → 'T [] →' State []) | ทำตัวเหมือนพับ แต่ส่งคืนผลลัพธ์ระดับกลางพร้อมกับผลลัพธ์สุดท้าย |
scanBack: ('T →' รัฐ→ 'รัฐ) →' T [] → 'รัฐ→' รัฐ [] | ทำงานเหมือน foldBack แต่ส่งคืนผลลัพธ์ตัวกลางพร้อมกับผลลัพธ์สุดท้าย |
ตั้งค่า: 'T [] → int →' T →หน่วย | ตั้งค่าองค์ประกอบของอาร์เรย์ |
จัดเรียง: 'T [] →' T [] | จัดเรียงองค์ประกอบของอาร์เรย์และส่งคืนอาร์เรย์ใหม่ Operators.compare ใช้เพื่อเปรียบเทียบองค์ประกอบ |
sortBy: ('T →' คีย์) → 'T [] →' T [] | จัดเรียงองค์ประกอบของอาร์เรย์โดยใช้ฟังก์ชันที่ให้มาเพื่อแปลงองค์ประกอบเป็นประเภทที่ใช้การดำเนินการจัดเรียงและส่งคืนอาร์เรย์ใหม่ Operators.compare ใช้เพื่อเปรียบเทียบองค์ประกอบ |
sortInPlace: 'T [] →หน่วย | จัดเรียงองค์ประกอบของอาร์เรย์โดยการเปลี่ยนอาร์เรย์ในตำแหน่งโดยใช้ฟังก์ชันเปรียบเทียบที่ให้มา Operators.compare ใช้เพื่อเปรียบเทียบองค์ประกอบ |
sortInPlaceBy: ('T →' Key) → 'T [] →หน่วย | จัดเรียงองค์ประกอบของอาร์เรย์โดยการเปลี่ยนอาร์เรย์ในตำแหน่งโดยใช้การฉายภาพที่ให้มาสำหรับคีย์ Operators.compare ใช้เพื่อเปรียบเทียบองค์ประกอบ |
sortInPlaceWith: ('T →' T → int) → 'T [] →หน่วย | จัดเรียงองค์ประกอบของอาร์เรย์โดยใช้ฟังก์ชันการเปรียบเทียบที่ให้มาเพื่อเปลี่ยนอาร์เรย์ในตำแหน่ง |
เรียงลำดับด้วย: ('T →' T → int) → 'T [] →' T [] | จัดเรียงองค์ประกอบของอาร์เรย์โดยใช้ฟังก์ชันการเปรียบเทียบที่ให้มาและส่งคืนอาร์เรย์ใหม่ |
ย่อย: 'T [] → int → int →' T [] | สร้างอาร์เรย์ที่มีช่วงย่อยที่ให้มาซึ่งระบุโดยดัชนีเริ่มต้นและความยาว |
ผลรวม: 'T [] → ^ T | ส่งคืนผลรวมขององค์ประกอบในอาร์เรย์ |
sumBy: ('T → ^ U) →' T [] → ^ U | ส่งกลับผลรวมของผลลัพธ์ที่สร้างขึ้นโดยใช้ฟังก์ชันกับแต่ละองค์ประกอบของอาร์เรย์ |
toList: รายการ 'T [] →' T | แปลงอาร์เรย์ที่ให้มาเป็นรายการ |
toSeq: 'T [] → seq <' T> | ดูอาร์เรย์ที่ให้มาเป็นลำดับ |
tryFind: ('T → bool) →' T [] → 'ตัวเลือก T | ส่งคืนองค์ประกอบแรกในอาร์เรย์ที่ให้มาซึ่งฟังก์ชันที่ให้มาจะส่งกลับ true. ผลตอบแทนNone หากไม่มีองค์ประกอบดังกล่าว |
tryFindIndex: ('T → bool) →' T [] →ตัวเลือก int | ส่งคืนดัชนีขององค์ประกอบแรกในอาร์เรย์ที่ตรงตามเงื่อนไขที่ระบุ |
tryPick: (ตัวเลือก 'T →' U) → 'T [] →' ตัวเลือก U | ใช้ฟังก์ชันที่ให้มากับองค์ประกอบต่อเนื่องของอาร์เรย์ที่ให้มาและส่งกลับผลลัพธ์แรกโดยที่ฟังก์ชันส่งคืนค่า Some (x) สำหรับบาง x ถ้าฟังก์ชันไม่คืนค่า Some (x)None จะถูกส่งกลับ |
เปิดเครื่องรูด: ('T1 *' T2) [] → 'T1 [] *' T2 [] | แบ่งอาร์เรย์ของคู่ทูเพิลเป็นทูเพิลสองอาร์เรย์ |
unzip3: ('T1 *' T2 * 'T3) [] →' T1 [] * 'T2 [] *' T3 [] | แยกอาร์เรย์ของทูเปิลของสามองค์ประกอบออกเป็นทูเพิลจากสามอาร์เรย์ |
zeroCreate: int → 'T [] | สร้างอาร์เรย์ที่องค์ประกอบเริ่มต้นถูกตั้งค่าเป็นค่าเริ่มต้น Unchecked.defaultof <'T> |
ซิป: 'T1 [] →' T2 [] → ('T1 *' T2) [] | รวมอาร์เรย์สองอาร์เรย์เข้ากับอาร์เรย์ของทูเปิลที่มีสององค์ประกอบ อาร์เรย์ทั้งสองต้องมีความยาวเท่ากัน มิฉะนั้น ArgumentException จะถูกยกขึ้น |
zip3: 'T1 [] →' T2 [] → 'T3 [] → (' T1 * 'T2 * 113' T3) [] | รวมอาร์เรย์สามอาร์เรย์เข้ากับอาร์เรย์ของสิ่งที่มีสามองค์ประกอบ อาร์เรย์ทั้งสามต้องมีความยาวเท่ากัน มิฉะนั้น ArgumentException จะถูกยกขึ้น |
ในส่วนต่อไปนี้เราจะเห็นการใช้ฟังก์ชันเหล่านี้บางส่วน
การสร้างอาร์เรย์โดยใช้ฟังก์ชัน
โมดูล Array มีฟังก์ชันมากมายที่สร้างอาร์เรย์ตั้งแต่เริ่มต้น
Array.empty ฟังก์ชันสร้างอาร์เรย์ว่างใหม่
Array.create ฟังก์ชันสร้างอาร์เรย์ของขนาดที่ระบุและตั้งค่าองค์ประกอบทั้งหมดเป็นค่าที่กำหนด
Array.init ฟังก์ชันสร้างอาร์เรย์กำหนดมิติข้อมูลและฟังก์ชันในการสร้างองค์ประกอบ
Array.zeroCreate ฟังก์ชันจะสร้างอาร์เรย์ซึ่งองค์ประกอบทั้งหมดจะเริ่มต้นเป็นค่าศูนย์
Array.copy ฟังก์ชันสร้างอาร์เรย์ใหม่ที่มีองค์ประกอบที่คัดลอกมาจากอาร์เรย์ที่มีอยู่
Array.sub ฟังก์ชันสร้างอาร์เรย์ใหม่จากช่วงย่อยของอาร์เรย์
Array.append ฟังก์ชันสร้างอาร์เรย์ใหม่โดยการรวมอาร์เรย์ที่มีอยู่สองอาร์เรย์
Array.choose ฟังก์ชันเลือกองค์ประกอบของอาร์เรย์เพื่อรวมไว้ในอาร์เรย์ใหม่
Array.collect ฟังก์ชันเรียกใช้ฟังก์ชันที่ระบุบนองค์ประกอบอาร์เรย์แต่ละรายการของอาร์เรย์ที่มีอยู่แล้วรวบรวมองค์ประกอบที่สร้างโดยฟังก์ชันและรวมเข้ากับอาร์เรย์ใหม่
Array.concat ฟังก์ชันใช้ลำดับของอาร์เรย์และรวมไว้ในอาร์เรย์เดียว
Array.filter ฟังก์ชันรับฟังก์ชันเงื่อนไขบูลีนและสร้างอาร์เรย์ใหม่ที่มีเฉพาะองค์ประกอบเหล่านั้นจากอาร์เรย์อินพุตที่เงื่อนไขเป็นจริง
Array.rev ฟังก์ชันสร้างอาร์เรย์ใหม่โดยการย้อนกลับลำดับของอาร์เรย์ที่มีอยู่
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงฟังก์ชันเหล่านี้ -
ตัวอย่าง 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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|]
ตัวอย่าง 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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|]
กำลังค้นหาอาร์เรย์
Array.find ฟังก์ชันรับฟังก์ชันบูลีนและส่งกลับองค์ประกอบแรกที่ฟังก์ชันคืนค่าเป็นจริงมิฉะนั้นจะเพิ่ม KeyNotFoundException
Array.findIndex ฟังก์ชันจะทำงานในทำนองเดียวกันยกเว้นว่าจะส่งกลับดัชนีขององค์ประกอบแทนที่จะเป็นองค์ประกอบนั้นเอง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้
Microsoft นำเสนอตัวอย่างโปรแกรมที่น่าสนใจซึ่งพบองค์ประกอบแรกในช่วงของจำนวนที่กำหนดซึ่งเป็นทั้งกำลังสองที่สมบูรณ์แบบและลูกบาศก์ที่สมบูรณ์แบบ -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
The first element that is both a square and a cube is 64 and its index is 62.
List<'T> คลาสแสดงถึงรายการอ็อบเจ็กต์ที่พิมพ์อย่างมากซึ่งดัชนีสามารถเข้าถึงได้
เป็นคู่ที่ไม่แน่นอนของคลาส List คล้ายกับอาร์เรย์เนื่องจากสามารถเข้าถึงได้ด้วยดัชนีอย่างไรก็ตามรายการสามารถปรับขนาดได้ต่างจากอาร์เรย์ ดังนั้นคุณไม่จำเป็นต้องระบุขนาดระหว่างการประกาศ
การสร้างรายการที่เปลี่ยนแปลงได้
รายการถูกสร้างขึ้นโดยใช้ newคีย์เวิร์ดและเรียกตัวสร้างรายการ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
(* 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])
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
0: Gone with the Wind
1: Atlas Shrugged
2: Fountainhead
3: Thornbirds
4: Rebecca
5: Narnia
รายการ (T) คลาส
คลาส List (T) แสดงถึงรายการอ็อบเจ็กต์ที่พิมพ์อย่างมากซึ่งดัชนีสามารถเข้าถึงได้ มีวิธีการค้นหาจัดเรียงและจัดการรายการ
ตารางต่อไปนี้แสดงคุณสมบัติตัวสร้างและวิธีการของคลาส List (T) -
คุณสมบัติ
ทรัพย์สิน | คำอธิบาย |
---|---|
ความจุ | รับหรือกำหนดจำนวนองค์ประกอบทั้งหมดที่โครงสร้างข้อมูลภายในสามารถเก็บไว้ได้โดยไม่ต้องปรับขนาด |
นับ | รับจำนวนองค์ประกอบที่มีอยู่ในรายการ (T) |
สิ่งของ | รับหรือตั้งค่าองค์ประกอบที่ดัชนีที่ระบุ |
ตัวสร้าง
ตัวสร้าง | คำอธิบาย |
---|---|
รายการ (T) () | เริ่มต้นอินสแตนซ์ใหม่ของคลาสรายการ (T) ที่ว่างเปล่าและมีความจุเริ่มต้นดีฟอลต์ |
รายการ (T) (IEnumerable (T)) | เริ่มต้นอินสแตนซ์ใหม่ของคลาส List (T) ที่มีองค์ประกอบที่คัดลอกมาจากคอลเล็กชันที่ระบุและมีความจุเพียงพอที่จะรองรับจำนวนองค์ประกอบที่คัดลอก |
รายการ (T) (Int32) | เริ่มต้นอินสแตนซ์ใหม่ของคลาส List (T) ที่ว่างเปล่าและมีความจุเริ่มต้นที่ระบุ |
วิธี
วิธีการ | คำอธิบาย |
---|---|
เพิ่ม | เพิ่มวัตถุที่ส่วนท้ายของรายการ (T) |
AddRange | เพิ่มองค์ประกอบของคอลเล็กชันที่ระบุไว้ที่ส่วนท้ายของรายการ (T) |
AsReadOnly | ส่งคืน wrapper IList (T) แบบอ่านอย่างเดียวสำหรับคอลเล็กชันปัจจุบัน |
BinarySearch (T) | ค้นหารายการที่เรียงลำดับทั้งหมด (T) สำหรับองค์ประกอบโดยใช้ตัวเปรียบเทียบเริ่มต้นและส่งกลับดัชนีที่ยึดตามองค์ประกอบเป็นศูนย์ |
BinarySearch (T, IComparer (T)) | ค้นหารายการที่เรียงลำดับทั้งหมด (T) สำหรับองค์ประกอบโดยใช้ตัวเปรียบเทียบที่ระบุและส่งกลับดัชนีที่อิงเป็นศูนย์ขององค์ประกอบ |
BinarySearch (Int32, Int32, T, IComparer (T)) | ค้นหาช่วงขององค์ประกอบในรายการที่เรียงลำดับ (T) สำหรับองค์ประกอบโดยใช้ตัวเปรียบเทียบที่ระบุและส่งกลับดัชนีที่อิงเป็นศูนย์ขององค์ประกอบ |
ชัดเจน | ลบองค์ประกอบทั้งหมดออกจากรายการ (T) |
ประกอบด้วย | กำหนดว่าองค์ประกอบอยู่ในรายการ (T) หรือไม่ |
แปลงทั้งหมด (TOutput) | แปลงองค์ประกอบในรายการปัจจุบัน (T) เป็นประเภทอื่นและส่งคืนรายการที่มีองค์ประกอบที่แปลงแล้ว |
CopyTo (T []) | คัดลอกรายการ (T) ทั้งหมดไปยังอาร์เรย์หนึ่งมิติที่เข้ากันได้โดยเริ่มจากจุดเริ่มต้นของอาร์เรย์เป้าหมาย |
CopyTo (T [], Int32) | คัดลอกรายการ (T) ทั้งหมดไปยังอาร์เรย์หนึ่งมิติที่เข้ากันได้โดยเริ่มจากดัชนีที่ระบุของอาร์เรย์เป้าหมาย |
CopyTo (Int32, T [], Int32, Int32) | คัดลอกช่วงขององค์ประกอบจากรายการ (T) ไปยังอาร์เรย์หนึ่งมิติที่เข้ากันได้โดยเริ่มจากดัชนีที่ระบุของอาร์เรย์เป้าหมาย |
เท่ากับ (วัตถุ) | กำหนดว่าวัตถุที่ระบุเท่ากับวัตถุปัจจุบันหรือไม่ (สืบทอดมาจาก Object) |
มีอยู่ | กำหนดว่ารายการ (T) มีองค์ประกอบที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุหรือไม่ |
สรุป | อนุญาตให้อ็อบเจ็กต์พยายามเพิ่มรีซอร์สและดำเนินการล้างข้อมูลอื่น ๆ ก่อนที่จะถูกเรียกคืนโดยการรวบรวมขยะ (รับมาจากอ็อบเจ็กต์) |
หา | ค้นหาองค์ประกอบที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุและส่งคืนค่าที่เกิดขึ้นครั้งแรกภายในรายการทั้งหมด (T) |
ค้นหาทั้งหมด | ดึงองค์ประกอบทั้งหมดที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุ |
FindIndex (เพรดิเคต (T)) | ค้นหาองค์ประกอบที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุและส่งกลับดัชนีที่อิงศูนย์ของเหตุการณ์แรกภายในรายการทั้งหมด (T) |
FindIndex (Int32, เพรดิเคต (T)) | ค้นหาองค์ประกอบที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุและส่งกลับดัชนีที่อิงศูนย์ของการเกิดครั้งแรกภายในช่วงขององค์ประกอบในรายการ (T) ที่ขยายจากดัชนีที่ระบุไปยังองค์ประกอบสุดท้าย |
FindIndex (Int32, Int32, เพรดิเคต (T)) | ค้นหาองค์ประกอบที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุและส่งกลับค่าดัชนีที่อิงศูนย์ของการเกิดครั้งแรกภายในช่วงขององค์ประกอบในรายการ (T) ที่เริ่มต้นที่ดัชนีที่ระบุและมีจำนวนองค์ประกอบที่ระบุ |
FindLast | ค้นหาองค์ประกอบที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุและส่งกลับค่าที่เกิดขึ้นสุดท้ายภายในรายการทั้งหมด (T) |
FindLastIndex (เพรดิเคต (T)) | ค้นหาองค์ประกอบที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุและส่งกลับดัชนีที่อิงศูนย์ของเหตุการณ์สุดท้ายภายในรายการทั้งหมด (T) |
FindLastIndex (Int32, เพรดิเคต (T)) | ค้นหาองค์ประกอบที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุและส่งกลับดัชนีที่อิงศูนย์ของเหตุการณ์สุดท้ายภายในช่วงขององค์ประกอบในรายการ (T) ที่ขยายจากองค์ประกอบแรกไปยังดัชนีที่ระบุ |
FindLastIndex (Int32, Int32, เพรดิเคต (T)) | ค้นหาองค์ประกอบที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุและส่งกลับดัชนีที่อิงศูนย์ของเหตุการณ์สุดท้ายภายในช่วงขององค์ประกอบในรายการ (T) ที่มีจำนวนองค์ประกอบที่ระบุและสิ้นสุดที่ดัชนีที่ระบุ |
แต่ละ | ดำเนินการตามที่ระบุในแต่ละองค์ประกอบของรายการ (T) |
GetEnumerator | ส่งคืนตัวแจงนับที่วนซ้ำผ่านรายการ (T) |
GetHashCode | ทำหน้าที่เป็นฟังก์ชันแฮชเริ่มต้น (สืบทอดมาจาก Object) |
GetRange | สร้างสำเนาตื้นของช่วงขององค์ประกอบในรายการแหล่งที่มา (T) |
GetType | รับประเภทของอินสแตนซ์ปัจจุบัน (สืบทอดมาจาก Object) |
ดัชนีของ (T) | ค้นหาอ็อบเจ็กต์ที่ระบุและส่งคืนดัชนีที่อิงเป็นศูนย์ของเหตุการณ์แรกภายในรายการทั้งหมด (T) |
ดัชนีของ (T, Int32) | ค้นหาออบเจ็กต์ที่ระบุและส่งกลับดัชนีที่อิงเป็นศูนย์ของการเกิดครั้งแรกภายในช่วงขององค์ประกอบในรายการ (T) ที่ขยายจากดัชนีที่ระบุไปยังองค์ประกอบสุดท้าย |
IndexOf (T, Int32, Int32) | ค้นหาออบเจ็กต์ที่ระบุและส่งกลับดัชนีที่อิงเป็นศูนย์ของการเกิดครั้งแรกภายในช่วงขององค์ประกอบในรายการ (T) ที่เริ่มต้นที่ดัชนีที่ระบุและมีจำนวนองค์ประกอบที่ระบุ |
แทรก | แทรกองค์ประกอบลงในรายการ (T) ที่ดัชนีที่ระบุ |
InsertRange | แทรกองค์ประกอบของคอลเลกชันในรายการ (T) ที่ดัชนีที่ระบุ |
LastIndexOf (T) | ค้นหาอ็อบเจ็กต์ที่ระบุและส่งกลับดัชนีที่อิงเป็นศูนย์ของเหตุการณ์สุดท้ายภายในรายการทั้งหมด (T) |
LastIndexOf (T, Int32) | ค้นหาออบเจ็กต์ที่ระบุและส่งกลับดัชนีที่อิงเป็นศูนย์ของเหตุการณ์สุดท้ายภายในช่วงขององค์ประกอบในรายการ (T) ที่ขยายจากองค์ประกอบแรกไปยังดัชนีที่ระบุ |
LastIndexOf (T, Int32, Int32) | ค้นหาอ็อบเจ็กต์ที่ระบุและส่งกลับดัชนีที่อิงเป็นศูนย์ของเหตุการณ์สุดท้ายภายในช่วงขององค์ประกอบในรายการ (T) ที่มีจำนวนองค์ประกอบที่ระบุและสิ้นสุดที่ดัชนีที่ระบุ |
MemberwiseClone | สร้างสำเนาตื้นของวัตถุปัจจุบัน (สืบทอดมาจาก Object) |
ลบ | ลบการเกิดขึ้นครั้งแรกของออบเจ็กต์เฉพาะจากรายการ (T) |
ลบทั้งหมด | ลบองค์ประกอบทั้งหมดที่ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุ |
RemoveAt | ลบองค์ประกอบที่ดัชนีที่ระบุของรายการ (T) |
RemoveRange | ลบช่วงขององค์ประกอบออกจากรายการ (T) |
ย้อนกลับ () | กลับลำดับขององค์ประกอบในรายการทั้งหมด (T) |
ย้อนกลับ (Int32, Int32) | กลับลำดับขององค์ประกอบในช่วงที่ระบุ |
จัดเรียง () | จัดเรียงองค์ประกอบในรายการทั้งหมด (T) โดยใช้ตัวเปรียบเทียบเริ่มต้น |
เรียงลำดับ (การเปรียบเทียบ (T)) | จัดเรียงองค์ประกอบในรายการ (T) ทั้งหมดโดยใช้ระบบที่ระบุ การเปรียบเทียบ (T) |
เรียง (IComparer (T)) | จัดเรียงองค์ประกอบในรายการทั้งหมด (T) โดยใช้ตัวเปรียบเทียบที่ระบุ |
เรียงลำดับ (Int32, Int32, IComparer (T)) | จัดเรียงองค์ประกอบในช่วงขององค์ประกอบในรายการ (T) โดยใช้ตัวเปรียบเทียบที่ระบุ |
ToArray | คัดลอกองค์ประกอบของรายการ (T) ไปยังอาร์เรย์ใหม่ |
ToString | ส่งคืนสตริงที่แสดงถึงวัตถุปัจจุบัน (สืบทอดมาจาก Object) |
TrimExcess | ตั้งค่าความจุเป็นจำนวนองค์ประกอบที่แท้จริงในรายการ (T) หากจำนวนนั้นน้อยกว่าค่าเกณฑ์ |
TrueForAll | กำหนดว่าทุกองค์ประกอบในรายการ (T) ตรงกับเงื่อนไขที่กำหนดโดยเพรดิเคตที่ระบุหรือไม่ |
ตัวอย่าง
(* 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])
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
Dictionary<'TKey, 'TValue> คลาสเป็นอะนาล็อกที่ไม่แน่นอนของโครงสร้างข้อมูลแผนที่ F # และมีฟังก์ชันเดียวกันมากมาย
สรุปจากบทแผนที่ใน F # แผนที่คือชุดพิเศษที่เชื่อมโยงค่ากับคีย์
การสร้างพจนานุกรมที่ไม่แน่นอน
พจนานุกรมที่ไม่แน่นอนถูกสร้างขึ้นโดยใช้ newคีย์เวิร์ดและเรียกตัวสร้างรายการ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Dictionary - students: seq
[[1501, Zara Ali]; [1502, Rishita Gupta]; [1503, Robin Sahoo];
[1504, Gillian Megan]]
คลาสพจนานุกรม (TKey, TValue)
คลาสพจนานุกรม (TKey, TValue) แสดงถึงชุดของคีย์และค่าต่างๆ
ตารางต่อไปนี้แสดงคุณสมบัติตัวสร้างและวิธีการของคลาส List (T) -
คุณสมบัติ
ทรัพย์สิน | คำอธิบาย |
---|---|
เปรียบเทียบ | รับ IEqualityComparer (T) ที่ใช้เพื่อกำหนดความเท่าเทียมกันของคีย์สำหรับพจนานุกรม |
นับ | รับจำนวนคู่คีย์ / ค่าที่มีอยู่ในพจนานุกรม (TKey, TValue) |
สิ่งของ | รับหรือตั้งค่าที่เกี่ยวข้องกับคีย์ที่ระบุ |
คีย์ | รับคอลเล็กชันที่มีคีย์ในพจนานุกรม (TKey, TValue) |
ค่า | รับคอลเล็กชันที่มีค่าในพจนานุกรม (TKey, TValue) |
ตัวสร้าง
ตัวสร้าง | คำอธิบาย |
---|---|
พจนานุกรม (TKey, TValue) () | เริ่มต้นอินสแตนซ์ใหม่ของไฟล์ Dictionary(TKey, TValue) คลาสที่ว่างมีความจุเริ่มต้นดีฟอลต์และใช้ตัวเปรียบเทียบความเท่าเทียมเริ่มต้นสำหรับประเภทคีย์ |
พจนานุกรม (TKey, TValue) (IDictionary (TKey, TValue)) | เริ่มต้นอินสแตนซ์ใหม่ของไฟล์ Dictionary(TKey, TValue) คลาสที่มีองค์ประกอบที่คัดลอกมาจากที่ระบุ IDictionary(TKey, TValue) และใช้ตัวเปรียบเทียบความเท่าเทียมเริ่มต้นสำหรับประเภทคีย์ |
พจนานุกรม (TKey, TValue) (IEqualityComparer (TKey)) | เริ่มต้นอินสแตนซ์ใหม่ของไฟล์ Dictionary(TKey, TValue) คลาสที่ว่างมีความจุเริ่มต้นเริ่มต้นและใช้ที่ระบุ IEqualityComparer(T). |
พจนานุกรม (TKey, TValue) (Int32) | เริ่มต้นอินสแตนซ์ใหม่ของไฟล์ Dictionary(TKey, TValue) คลาสที่ว่างมีความจุเริ่มต้นที่ระบุและใช้ตัวเปรียบเทียบความเท่าเทียมดีฟอลต์สำหรับประเภทคีย์ |
พจนานุกรม (TKey, TValue) (IDictionary (TKey, TValue), IEqualityComparer (TKey)) | เริ่มต้นอินสแตนซ์ใหม่ของไฟล์ Dictionary(TKey, TValue) คลาสที่มีองค์ประกอบที่คัดลอกมาจากที่ระบุ IDictionary(TKey, TValue) และใช้ไฟล์ IEqualityComparer(T). |
พจนานุกรม (TKey, TValue) (Int32, IEqualityComparer (TKey)) | เริ่มต้นอินสแตนซ์ใหม่ของไฟล์ Dictionary(TKey, TValue) คลาสที่ว่างมีความจุเริ่มต้นที่ระบุและใช้ที่ระบุ IEqualityComparer(T). |
พจนานุกรม (TKey, TValue) (SerializationInfo, StreamingContext) | เริ่มต้นอินสแตนซ์ใหม่ของไฟล์ ictionary(TKey, TValue) คลาสที่มีข้อมูลอนุกรม |
วิธีการ
วิธี | คำอธิบาย |
---|---|
เพิ่ม | เพิ่มคีย์และค่าที่ระบุลงในพจนานุกรม |
ชัดเจน | ลบคีย์และค่าทั้งหมดออกจากพจนานุกรม (TKey, TValue) |
ประกอบด้วยคีย์ | กำหนดว่าพจนานุกรม (TKey, TValue) มีคีย์ที่ระบุหรือไม่ |
ประกอบด้วยค่า | กำหนดว่าพจนานุกรม (TKey, TValue) มีค่าเฉพาะหรือไม่ |
เท่ากับ (วัตถุ) | กำหนดว่าวัตถุที่ระบุเท่ากับวัตถุปัจจุบันหรือไม่ (สืบทอดมาจาก Object) |
สรุป | อนุญาตให้ออบเจ็กต์พยายามปลดปล่อยทรัพยากรและดำเนินการล้างข้อมูลอื่น ๆ ก่อนที่จะเรียกคืนโดยการรวบรวมขยะ (สืบทอดมาจาก Object) |
GetEnumerator | ส่งคืนตัวแจงนับที่วนซ้ำผ่านพจนานุกรม (TKey, TValue) |
GetHashCode | ทำหน้าที่เป็นฟังก์ชันแฮชเริ่มต้น (สืบทอดมาจาก Object) |
GetObjectData | ใช้อินเทอร์เฟซ System.Runtime.Serialization.ISerializable และส่งคืนข้อมูลที่จำเป็นในการทำให้อินสแตนซ์ Dictionary (TKey, TValue) เป็นอนุกรม |
GetType | รับประเภทของอินสแตนซ์ปัจจุบัน (สืบทอดมาจาก Object) |
MemberwiseClone | สร้างสำเนาตื้นของวัตถุปัจจุบัน (สืบทอดมาจาก Object) |
OnDeserialization | ใช้อินเทอร์เฟซ System.Runtime.Serialization.ISerializable และเพิ่มเหตุการณ์ deserialization เมื่อการ deserialization เสร็จสมบูรณ์ |
ลบ | ลบค่าด้วยคีย์ที่ระบุจากพจนานุกรม (TKey, TValue) |
ToString | ส่งคืนสตริงที่แสดงถึงวัตถุปัจจุบัน (สืบทอดมาจาก Object) |
TryGetValue | รับค่าที่เกี่ยวข้องกับคีย์ที่ระบุ |
ตัวอย่าง
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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"]
อินพุตเอาต์พุตพื้นฐานประกอบด้วย -
- การอ่านและเขียนลงในคอนโซล
- การอ่านและเขียนลงในไฟล์
โมดูล Core.Printf
เราใช้ฟังก์ชัน printfและprintfnเพื่อเขียนลงในคอนโซล ในส่วนนี้เราจะดูรายละเอียดของไฟล์Printf โมดูลของ F #
นอกเหนือจากฟังก์ชั่นข้างต้นโมดูลCore.Printfของ F # ยังมีวิธีการอื่น ๆ อีกมากมายสำหรับการพิมพ์และการจัดรูปแบบโดยใช้เครื่องหมาย% เป็นตัวยึดตำแหน่ง ตารางต่อไปนี้แสดงวิธีการพร้อมคำอธิบายสั้น ๆ -
มูลค่า | คำอธิบาย |
---|---|
bprintf: StringBuilder → BuilderFormat <'T> →' T | พิมพ์ไปยัง StringBuilder |
eprintf: TextWriterFormat <'T> →' T | พิมพ์เอาต์พุตที่จัดรูปแบบไปยัง stderr |
eprintfn: TextWriterFormat <'T> →' T | พิมพ์เอาต์พุตที่จัดรูปแบบไปยัง stderr เพิ่มบรรทัดใหม่ |
failwithf: StringFormat <'T,' Result> → 'T | พิมพ์ไปยังสตริงบัฟเฟอร์และทำให้เกิดข้อยกเว้นกับผลลัพธ์ที่กำหนด |
fprintf: TextWriter → TextWriterFormat <'T> →' T | พิมพ์ไปยังเครื่องเขียนข้อความ |
fprintfn: TextWriter → TextWriterFormat <'T> →' T | พิมพ์ไปยังเครื่องเขียนข้อความเพิ่มบรรทัดใหม่ |
kbprintf: (หน่วย→ 'ผลลัพธ์) → StringBuilder → BuilderFormat <' T, 'ผลลัพธ์> →' T | เช่นเดียวกับ bprintf แต่เรียกใช้ฟังก์ชันที่ระบุเพื่อสร้างผลลัพธ์ |
kfprintf: (หน่วย→ 'ผลลัพธ์) → TextWriter → TextWriterFormat <' T, 'ผลลัพธ์> →' T | เช่นเดียวกับ fprintf แต่เรียกใช้ฟังก์ชันที่ระบุเพื่อสร้างผลลัพธ์ |
kprintf: (สตริง→ 'ผลลัพธ์) → StringFormat <' T, 'ผลลัพธ์> →' T | เช่นเดียวกับ printf แต่เรียกใช้ฟังก์ชันที่ระบุเพื่อสร้างผลลัพธ์ ตัวอย่างเช่นสิ่งเหล่านี้ปล่อยให้แรงพิมพ์หลังจากป้อนเอาต์พุตทั้งหมดลงในช่องสัญญาณ แต่ไม่เกิดขึ้นก่อนหน้านี้ |
ksprintf: (สตริง→ 'ผลลัพธ์) → StringFormat <' T, 'ผลลัพธ์> →' T | เช่นเดียวกับ sprintf แต่เรียกใช้ฟังก์ชันที่ระบุเพื่อสร้างผลลัพธ์ |
printf: TextWriterFormat <'T> →' T | พิมพ์เอาต์พุตที่จัดรูปแบบเป็น stdout |
printfn: TextWriterFormat <'T> →' T | พิมพ์เอาต์พุตที่จัดรูปแบบเป็น stdout เพิ่มขึ้นบรรทัดใหม่ |
sprintf: StringFormat <'T> →' T | พิมพ์เป็นสตริงโดยใช้บัฟเฟอร์สตริงภายในและส่งคืนผลลัพธ์เป็นสตริง |
ข้อกำหนดรูปแบบ
ข้อกำหนดรูปแบบใช้สำหรับจัดรูปแบบอินพุตหรือเอาต์พุตตามความต้องการของโปรแกรมเมอร์
นี่คือสตริงที่มีเครื่องหมาย% ระบุตัวยึดรูปแบบ
ไวยากรณ์ของตัวยึดรูปแบบคือ -
%[flags][width][.precision][type]
type ถูกตีความว่า -
ประเภท | คำอธิบาย |
---|---|
% ข | รูปแบบไฟล์ bool, จัดรูปแบบเป็น true หรือ false. |
%ค | จัดรูปแบบอักขระ |
% s | รูปแบบไฟล์ string, จัดรูปแบบเป็นเนื้อหาโดยไม่ต้องตีความอักขระหลีกใด ๆ |
% d,% i | จัดรูปแบบประเภทจำนวนเต็มพื้นฐานใด ๆ ที่จัดรูปแบบเป็นจำนวนเต็มทศนิยมโดยจะเซ็นชื่อหากประเภทจำนวนเต็มพื้นฐานถูกเซ็น |
%ยู | จัดรูปแบบประเภทจำนวนเต็มพื้นฐานที่จัดรูปแบบเป็นจำนวนเต็มทศนิยมที่ไม่ได้ลงชื่อ |
% x | จัดรูปแบบประเภทจำนวนเต็มพื้นฐานใด ๆ ที่จัดรูปแบบเป็นจำนวนเต็มฐานสิบหกที่ไม่ได้ลงชื่อโดยใช้อักษรตัวพิมพ์เล็ก a ถึง f |
% X | จัดรูปแบบประเภทจำนวนเต็มพื้นฐานใด ๆ ที่จัดรูปแบบเป็นจำนวนเต็มฐานสิบหกที่ไม่ได้ลงชื่อโดยใช้อักษรตัวพิมพ์ใหญ่ A ถึง F |
% o | จัดรูปแบบประเภทจำนวนเต็มพื้นฐานที่จัดรูปแบบเป็นจำนวนเต็มฐานแปดที่ไม่ได้ลงนาม |
% e,% E,% f,% F,% g,% G | จัดรูปแบบประเภทจุดลอยตัวพื้นฐาน (float, float32) จัดรูปแบบโดยใช้ข้อกำหนดรูปแบบจุดลอยตัวสไตล์ C |
% e,% E | จัดรูปแบบค่าที่ลงนามโดยมีรูปแบบ [-] d.dddde [sign] ddd โดยที่ d เป็นเลขฐานสิบเดียว dddd คือทศนิยมหนึ่งหลักขึ้นไป ddd คือทศนิยมสามหลักและเครื่องหมายคือ + หรือ - |
% ฉ | จัดรูปแบบค่าที่ลงนามโดยมีรูปแบบ [-] dddd.dddd โดยที่ dddd เป็นตัวเลขทศนิยมหนึ่งหลักขึ้นไป จำนวนหลักก่อนจุดทศนิยมขึ้นอยู่กับขนาดของตัวเลขและจำนวนหลักหลังจุดทศนิยมขึ้นอยู่กับความแม่นยำที่ร้องขอ |
% ก.% ก | จัดรูปแบบค่าที่ลงนามซึ่งพิมพ์ในรูปแบบ f หรือ e แล้วแต่ว่าค่าใดจะกะทัดรัดกว่าสำหรับค่าที่กำหนดและความแม่นยำ |
% ม | จัดรูปแบบค่าทศนิยม |
% O | จัดรูปแบบค่าใด ๆ พิมพ์โดยการชกมวยวัตถุและใช้ ToString วิธี. |
% ก% + ก | จัดรูปแบบค่าใด ๆ ที่พิมพ์ด้วยการตั้งค่าโครงร่างเริ่มต้น ใช้% + A เพื่อพิมพ์โครงสร้างของสหภาพแรงงานที่เลือกปฏิบัติด้วยการเป็นตัวแทนภายในและส่วนตัว |
% ก | ตัวระบุรูปแบบทั่วไปต้องการสองอาร์กิวเมนต์ อาร์กิวเมนต์แรกคือฟังก์ชันที่ยอมรับสองอาร์กิวเมนต์: อันดับแรกพารามิเตอร์บริบทของชนิดที่เหมาะสมสำหรับฟังก์ชันการจัดรูปแบบที่กำหนด (ตัวอย่างเช่น TextWriter) และค่าที่สองคือค่าที่จะพิมพ์และซึ่งส่งออกหรือส่งคืนข้อความที่เหมาะสม อาร์กิวเมนต์ที่สองคือค่าเฉพาะที่จะพิมพ์ |
% t | ตัวระบุรูปแบบทั่วไปต้องการหนึ่งอาร์กิวเมนต์: ฟังก์ชันที่ยอมรับพารามิเตอร์บริบทของชนิดที่เหมาะสมสำหรับฟังก์ชันการจัดรูปแบบที่กำหนด (aTextWriter) และซึ่งเอาต์พุตหรือส่งคืนข้อความที่เหมาะสม ประเภทจำนวนเต็มพื้นฐานคือbyte, sbyte, int16, uint16, int32, uint32, int64, uint64, nativeint, และ unativeint. ประเภทจุดลอยตัวพื้นฐานคือ float และ float32. |
widthเป็นพารามิเตอร์ทางเลือก เป็นจำนวนเต็มที่ระบุความกว้างน้อยที่สุดของผลลัพธ์ ตัวอย่างเช่น% 5d พิมพ์จำนวนเต็มโดยมีช่องว่างอย่างน้อย 5 อักขระ
ถูกต้อง flags อธิบายไว้ในตารางต่อไปนี้ -
มูลค่า | คำอธิบาย |
---|---|
0 | ระบุเพื่อเพิ่มศูนย์แทนช่องว่างเพื่อสร้างความกว้างที่ต้องการ |
- | ระบุเพื่อจัดชิดซ้ายให้ผลลัพธ์ภายในความกว้างที่ระบุ |
+ | ระบุเพื่อเพิ่มอักขระ + หากตัวเลขเป็นค่าบวก (เพื่อให้ตรงกับเครื่องหมาย - สำหรับจำนวนลบ) |
'' (ช่องว่าง) | ระบุเพื่อเพิ่มช่องว่างหากตัวเลขเป็นค่าบวก (เพื่อให้ตรงกับเครื่องหมาย - สำหรับจำนวนลบ) |
# | ไม่ถูกต้อง |
ตัวอย่าง
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
คลาสคอนโซล
คลาสนี้เป็นส่วนหนึ่งของ. NET framework แสดงถึงอินพุตเอาต์พุตและสตรีมข้อผิดพลาดมาตรฐานสำหรับแอปพลิเคชันคอนโซล
มีวิธีการต่างๆในการอ่านและเขียนลงในคอนโซล ตารางต่อไปนี้แสดงวิธีการ -
วิธี | คำอธิบาย |
---|---|
บี๊บ () | เล่นเสียงบี๊บผ่านลำโพงคอนโซล |
เสียงเตือน (Int32, Int32) | เล่นเสียงบี๊บตามความถี่และระยะเวลาที่กำหนดผ่านลำโพงคอนโซล |
ชัดเจน | ล้างบัฟเฟอร์คอนโซลและหน้าต่างคอนโซลที่เกี่ยวข้องของข้อมูลการแสดงผล |
MoveBufferArea (Int32, Int32, Int32, Int32, Int32, Int32) | คัดลอกพื้นที่ต้นทางที่ระบุของบัฟเฟอร์หน้าจอไปยังพื้นที่ปลายทางที่ระบุ |
MoveBufferArea (Int32, Int32, Int32, Int32, Int32, Int32, Char, ConsoleColor, ConsoleColor) | คัดลอกพื้นที่ต้นทางที่ระบุของบัฟเฟอร์หน้าจอไปยังพื้นที่ปลายทางที่ระบุ |
OpenStandardError () | รับสตรีมข้อผิดพลาดมาตรฐาน |
OpenStandardError (Int32) | รับสตรีมข้อผิดพลาดมาตรฐานซึ่งตั้งค่าเป็นขนาดบัฟเฟอร์ที่ระบุ |
OpenStandardInput () | รับสตรีมอินพุตมาตรฐาน |
OpenStandardInput (Int32) | รับสตรีมอินพุตมาตรฐานซึ่งกำหนดเป็นขนาดบัฟเฟอร์ที่ระบุ |
OpenStandardOutput () | รับสตรีมเอาต์พุตมาตรฐาน |
OpenStandardOutput (Int32) | รับสตรีมเอาต์พุตมาตรฐานซึ่งตั้งค่าเป็นขนาดบัฟเฟอร์ที่ระบุ |
อ่าน | อ่านอักขระถัดไปจากสตรีมอินพุตมาตรฐาน |
ReadKey () | รับอักขระถัดไปหรือปุ่มฟังก์ชันที่ผู้ใช้กด ปุ่มกดจะปรากฏในหน้าต่างคอนโซล |
ReadKey (บูลีน) | รับอักขระถัดไปหรือปุ่มฟังก์ชันที่ผู้ใช้กด ปุ่มกดจะแสดงเป็นทางเลือกในหน้าต่างคอนโซล |
ReadLine | อ่านบรรทัดถัดไปของอักขระจากสตรีมอินพุตมาตรฐาน |
รีเซ็ตสี | ตั้งค่าสีคอนโซลเบื้องหน้าและพื้นหลังเป็นค่าเริ่มต้น |
SetBufferSize | ตั้งค่าความสูงและความกว้างของพื้นที่บัฟเฟอร์หน้าจอเป็นค่าที่ระบุ |
SetCursorPosition | กำหนดตำแหน่งของเคอร์เซอร์ |
SetError | ตั้งค่าคุณสมบัติข้อผิดพลาดเป็นวัตถุTextWriter ที่ระบุ |
ที่ตั้งอยู่ใน | ตั้งค่าคุณสมบัติ In เป็นอ็อบเจ็กต์TextReader ที่ระบุ |
SetOut | ตั้งค่าคุณสมบัติ Out เป็นอ็อบเจ็กต์TextWriter ที่ระบุ |
SetWindowPosition | ตั้งค่าตำแหน่งของหน้าต่างคอนโซลที่สัมพันธ์กับบัฟเฟอร์หน้าจอ |
SetWindowSize | ตั้งค่าความสูงและความกว้างของหน้าต่างคอนโซลเป็นค่าที่ระบุ |
เขียน (บูลีน) | เขียนการแสดงข้อความของค่าบูลีนที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (Char) | เขียนค่าอักขระ Unicode ที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (Char []) | เขียนอาร์เรย์ของอักขระ Unicode ที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (ทศนิยม) | เขียนการแสดงข้อความของค่าทศนิยมที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (คู่) | เขียนการแสดงข้อความของค่าทศนิยมที่มีความแม่นยำสองเท่าที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (Int32) | เขียนการแสดงข้อความของค่าจำนวนเต็มลายเซ็น 32 บิตที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (Int64) | เขียนการแสดงข้อความของค่าจำนวนเต็มลายเซ็น 64 บิตที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (วัตถุ) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (เดี่ยว) | เขียนการแสดงข้อความของค่าทศนิยมความแม่นยำเดียวที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (สตริง) | เขียนค่าสตริงที่ระบุไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (UInt32) | เขียนการแสดงข้อความของค่าจำนวนเต็ม 32 บิตที่ไม่ได้ลงชื่อไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (UInt64) | เขียนการแสดงข้อความของค่าจำนวนเต็ม 64 บิตที่ไม่ได้ลงชื่อไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (String, Object) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
เขียน (String, Object []) | เขียนการแสดงข้อความของอาร์เรย์ของอ็อบเจ็กต์ที่ระบุไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
เขียน (Char [], Int32, Int32) | เขียนซับเรย์ที่ระบุของอักขระ Unicode ไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียน (String, Object, Object) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
เขียน (String, Object, Object, Object) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
เขียน (String, Object, Object, Object, Object) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุและรายการพารามิเตอร์ความยาวตัวแปรไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
เขียนบรรทัด () | เขียนเทอร์มิเนเตอร์บรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (บูลีน) | เขียนการแสดงข้อความของค่าบูลีนที่ระบุตามด้วยเทอร์มิเนเตอร์บรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (ถ่าน) | เขียนอักขระ Unicode ที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันค่าไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (ถ่าน []) | เขียนอาร์เรย์ของอักขระ Unicode ที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (ทศนิยม) | เขียนการแสดงข้อความของค่าทศนิยมที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (คู่) | เขียนการแสดงข้อความของค่าทศนิยมที่มีความแม่นยำสองเท่าที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียนไลน์ (Int32) | เขียนการแสดงข้อความของค่าจำนวนเต็มลายเซ็น 32 บิตที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
เขียนไลน์ (Int64) | เขียนการแสดงข้อความของค่าจำนวนเต็มลายเซ็น 64 บิตที่ระบุตามด้วยเทอร์มิเนเตอร์บรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (วัตถุ) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุตามด้วยเทอร์มิเนเตอร์บรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (เดี่ยว) | เขียนการแสดงข้อความของค่าทศนิยมความแม่นยำเดียวที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (สตริง) | เขียนค่าสตริงที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (UInt32) | เขียนการแสดงข้อความของค่าจำนวนเต็ม 32 บิตที่ไม่ได้ลงชื่อตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (UInt64) | เขียนการแสดงข้อความของค่าจำนวนเต็ม 64 บิตที่ไม่ได้ลงชื่อตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (สตริงวัตถุ) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
WriteLine (สตริงวัตถุ []) | เขียนการแสดงข้อความของอาร์เรย์ของอ็อบเจ็กต์ที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
WriteLine (ถ่าน [], Int32, Int32) | เขียนซับเรย์ที่ระบุของอักขระ Unicode ตามด้วยเทอร์มิเนเตอร์บรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐาน |
WriteLine (สตริงวัตถุวัตถุ) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
WriteLine (สตริงวัตถุวัตถุวัตถุ) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
WriteLine (สตริง, วัตถุ, วัตถุ, วัตถุ, วัตถุ) | เขียนการแสดงข้อความของอ็อบเจ็กต์ที่ระบุและรายการพารามิเตอร์ที่มีความยาวตัวแปรตามด้วยตัวยุติบรรทัดปัจจุบันไปยังสตรีมเอาต์พุตมาตรฐานโดยใช้ข้อมูลรูปแบบที่ระบุ |
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการอ่านจากคอนโซลและการเขียนลงในนั้น -
ตัวอย่าง
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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
What's your name? Kabir
Hello, Kabir
Big Greetings from TutorialsPoint and Absoulte Classes
|2015-Jan-05|
เนมสเปซ System.IO
เนมสเปซ System.IO มีคลาสที่มีประโยชน์มากมายสำหรับการดำเนินการ I / O พื้นฐาน
ประกอบด้วยประเภทหรือคลาสที่อนุญาตให้อ่านและเขียนไปยังไฟล์สตรีมข้อมูลและประเภทที่ให้การสนับสนุนไฟล์และไดเร็กทอรีพื้นฐาน
คลาสที่มีประโยชน์สำหรับการทำงานกับระบบไฟล์ -
- คลาส System.IO.File ใช้สำหรับการสร้างต่อท้ายและลบไฟล์
- คลาส System.IO.Directory ใช้สำหรับสร้างย้ายและลบไดเร็กทอรี
- คลาส System.IO.Path ดำเนินการกับสตริงซึ่งแสดงถึงเส้นทางไฟล์
- คลาส System.IO.FileSystemWatcher อนุญาตให้ผู้ใช้ฟังไดเร็กทอรีสำหรับการเปลี่ยนแปลง
คลาสที่มีประโยชน์สำหรับการทำงานกับสตรีม (ลำดับไบต์) -
- คลาส System.IO.StreamReader ใช้เพื่ออ่านอักขระจากสตรีม
- คลาส System.IO.StreamWriter ใช้ในการเขียนอักขระลงในสตรีม
- คลาส System.IO.MemoryStream สร้างสตรีมไบต์ในหน่วยความจำ
ตารางต่อไปนี้แสดงคลาสทั้งหมดที่มีให้ในเนมสเปซพร้อมกับคำอธิบายสั้น ๆ -
คลาส | คำอธิบาย |
---|---|
BinaryReader | อ่านชนิดข้อมูลดั้งเดิมเป็นค่าไบนารีในการเข้ารหัสเฉพาะ |
BinaryWriter | เขียนประเภทดั้งเดิมในไบนารีไปยังสตรีมและสนับสนุนการเขียนสตริงในการเข้ารหัสเฉพาะ |
บัฟเฟอร์สตรีม | เพิ่มเลเยอร์บัฟเฟอร์เพื่ออ่านและเขียนการดำเนินการบนสตรีมอื่น |
ไดเรกทอรี | แสดงวิธีการแบบคงที่สำหรับการสร้างย้ายและระบุผ่านไดเร็กทอรีและไดเร็กทอรีย่อย |
DirectoryInfo | แสดงวิธีการของอินสแตนซ์สำหรับการสร้างย้ายและระบุผ่านไดเร็กทอรีและไดเร็กทอรีย่อย |
DirectoryNotFoundException | ข้อยกเว้นที่เกิดขึ้นเมื่อไม่พบส่วนของไฟล์หรือไดเร็กทอรี |
DriveInfo | ให้การเข้าถึงข้อมูลบนไดรฟ์ |
DriveNotFoundException | ข้อยกเว้นที่เกิดขึ้นเมื่อพยายามเข้าถึงไดรฟ์หรือแชร์ที่ไม่พร้อมใช้งาน |
EndOfStreamException | ข้อยกเว้นที่เกิดขึ้นเมื่อพยายามอ่านผ่านจุดสิ้นสุดของสตรีม |
ErrorEventArgs | จัดเตรียมข้อมูลสำหรับเหตุการณ์ FileSystemWatcher.Error |
ไฟล์ | จัดเตรียมวิธีการคงที่สำหรับการสร้างการคัดลอกการลบการย้ายและการเปิดไฟล์เดียวและช่วยในการสร้างอ็อบเจ็กต์ FileStream |
FileFormatException | ข้อยกเว้นที่เกิดขึ้นเมื่อไฟล์อินพุตหรือสตรีมข้อมูลที่ควรเป็นไปตามข้อกำหนดรูปแบบไฟล์บางรูปแบบผิดรูปแบบ |
FileInfo | จัดเตรียมคุณสมบัติและวิธีการอินสแตนซ์สำหรับการสร้างการคัดลอกการลบการย้ายและการเปิดไฟล์และช่วยในการสร้างอ็อบเจ็กต์ FileStream |
FileLoadException | ข้อยกเว้นที่เกิดขึ้นเมื่อพบแอสเซมบลีที่มีการจัดการ แต่ไม่สามารถโหลดได้ |
FileNotFoundException | ข้อยกเว้นที่เกิดขึ้นเมื่อความพยายามเข้าถึงไฟล์ที่ไม่มีอยู่บนดิสก์ล้มเหลว |
FileStream | แสดงสตรีมรอบ ๆ ไฟล์ซึ่งสนับสนุนการดำเนินการอ่านและเขียนทั้งแบบซิงโครนัสและอะซิงโครนัส |
FileSystemEventArgs | จัดเตรียมข้อมูลสำหรับเหตุการณ์ในไดเร็กทอรี - เปลี่ยนแปลงสร้างลบ |
FileSystemInfo | จัดเตรียมคลาสพื้นฐานสำหรับอ็อบเจ็กต์ FileInfo และ DirectoryInfo |
FileSystemWatcher | รับฟังการแจ้งเตือนการเปลี่ยนแปลงระบบไฟล์และเพิ่มเหตุการณ์เมื่อไดเร็กทอรีหรือไฟล์ในไดเร็กทอรีเปลี่ยนแปลง |
InternalBufferOverflowException | เกิดข้อยกเว้นเมื่อบัฟเฟอร์ภายในล้น |
InvalidDataException | ข้อยกเว้นที่เกิดขึ้นเมื่อสตรีมข้อมูลอยู่ในรูปแบบที่ไม่ถูกต้อง |
IODescriptionAttribute | ตั้งค่าตัวออกแบบวิชวลคำอธิบายสามารถแสดงเมื่ออ้างถึงเหตุการณ์ส่วนขยายหรือคุณสมบัติ |
IOException | ข้อยกเว้นที่เกิดขึ้นเมื่อเกิดข้อผิดพลาด I / O |
MemoryStream | สร้างสตรีมที่มีที่เก็บสำรองเป็นหน่วยความจำ |
เส้นทาง | ดำเนินการกับอินสแตนซ์ String ที่มีข้อมูลไฟล์หรือไดเร็กทอรีพา ธ การดำเนินการเหล่านี้ดำเนินการในลักษณะข้ามแพลตฟอร์ม |
PathTooLongException | ข้อยกเว้นที่เกิดขึ้นเมื่อพา ธ หรือชื่อไฟล์ยาวเกินความยาวสูงสุดที่ระบบกำหนด |
PipeException | โยนเมื่อเกิดข้อผิดพลาดภายในไปป์ที่ระบุชื่อ |
RenamedEventArgs | ให้ข้อมูลสำหรับเหตุการณ์ที่เปลี่ยนชื่อ |
กระแส | ให้มุมมองทั่วไปของลำดับไบต์ นี่คือคลาสนามธรรม |
StreamReader | ใช้ TextReader ที่อ่านอักขระจากสตรีมไบต์ในการเข้ารหัสเฉพาะ |
StreamWriter | ใช้ TextWriter สำหรับการเขียนอักขระไปยังสตรีมในการเข้ารหัสเฉพาะ ในการเรียกดูซอร์สโค้ด. NET Framework สำหรับประเภทนี้โปรดดูที่แหล่งอ้างอิง |
StringReader | ใช้ TextReader ที่อ่านจากสตริง |
StringWriter | ใช้ TextWriter สำหรับการเขียนข้อมูลลงในสตริง ข้อมูลจะถูกเก็บไว้ใน StringBuilder ที่อยู่ภายใต้ |
TextReader | หมายถึงผู้อ่านที่สามารถอ่านชุดอักขระตามลำดับได้ |
TextWriter | แสดงถึงผู้เขียนที่สามารถเขียนชุดอักขระตามลำดับได้ ชั้นนี้เป็นนามธรรม |
UnmanagedMemoryAccessor | ให้การเข้าถึงแบบสุ่มไปยังบล็อกหน่วยความจำที่ไม่มีการจัดการจากรหัสที่มีการจัดการ |
UnmanagedMemoryStream | ให้การเข้าถึงบล็อกหน่วยความจำที่ไม่มีการจัดการจากโค้ดที่มีการจัดการ |
WindowsRuntimeStorageExtensions | มีเมธอดส่วนขยายสำหรับอินเทอร์เฟซ IStorageFile และ IStorageFolder ใน Windows Runtime เมื่อพัฒนาแอป Windows Store |
WindowsRuntimeStreamExtensions | มีวิธีการส่วนขยายสำหรับการแปลงระหว่างสตรีมใน Windows Runtime และสตรีมที่มีการจัดการในแอป. NET สำหรับ Windows Store |
ตัวอย่าง
ตัวอย่างต่อไปนี้สร้างไฟล์ชื่อ test.txt เขียนข้อความที่นั่นอ่านข้อความจากไฟล์และพิมพ์บนคอนโซล
Note - จำนวนรหัสที่ต้องใช้ในการทำสิ่งนี้น้อยลงอย่างน่าตกใจ!
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Hello There
Welcome to:
Tutorials Point
Generics ช่วยให้คุณสามารถชะลอการกำหนดประเภทข้อมูลขององค์ประกอบการเขียนโปรแกรมในคลาสหรือวิธีการได้จนกว่าจะมีการใช้งานจริงในโปรแกรม กล่าวอีกนัยหนึ่ง generics ช่วยให้คุณสามารถเขียนคลาสหรือวิธีการที่สามารถทำงานกับข้อมูลประเภทใดก็ได้
คุณเขียนข้อกำหนดสำหรับคลาสหรือเมธอดโดยมีพารามิเตอร์ทดแทนสำหรับชนิดข้อมูล เมื่อคอมไพลเลอร์พบคอนสตรัคเตอร์สำหรับคลาสหรือการเรียกใช้ฟังก์ชันสำหรับเมธอดคอมไพเลอร์จะสร้างโค้ดเพื่อจัดการกับชนิดข้อมูลเฉพาะ
ใน F # ค่าฟังก์ชันวิธีการคุณสมบัติและประเภทการรวมเช่นคลาสเรกคอร์ดและยูเนี่ยนที่แบ่งแยกสามารถเป็นค่าทั่วไปได้
โครงสร้างทั่วไปมีพารามิเตอร์ประเภทอย่างน้อยหนึ่งรายการ ฟังก์ชันและประเภททั่วไปช่วยให้คุณสามารถเขียนโค้ดที่ใช้งานได้กับประเภทต่างๆโดยไม่ต้องใช้รหัสซ้ำสำหรับแต่ละประเภท
ไวยากรณ์
ไวยากรณ์สำหรับการเขียนโครงสร้างทั่วไปมีดังนี้ -
// 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
ตัวอย่าง
(* Generic Function *)
let printFunc<'T> x y =
printfn "%A, %A" x y
printFunc<float> 10.0 20.0
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
10.0, 20.0
คุณยังสามารถสร้างฟังก์ชันทั่วไปโดยใช้ไวยากรณ์ของเครื่องหมายอัญประกาศเดี่ยว -
(* Generic Function *)
let printFunction (x: 'a) (y: 'a) =
printfn "%A %A" x y
printFunction 10.0 20.0
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
10.0 20.0
โปรดทราบว่าเมื่อคุณใช้ฟังก์ชันหรือวิธีการทั่วไปคุณอาจไม่ต้องระบุประเภทอาร์กิวเมนต์ อย่างไรก็ตามในกรณีที่มีความคลุมเครือคุณสามารถระบุประเภทอาร์กิวเมนต์ในวงเล็บเหลี่ยมได้เหมือนที่เราทำในตัวอย่างแรก
หากคุณมีมากกว่าหนึ่งประเภทให้แยกอาร์กิวเมนต์หลายประเภทด้วยเครื่องหมายจุลภาค
คลาสทั่วไป
เช่นเดียวกับฟังก์ชันทั่วไปคุณสามารถเขียนคลาสทั่วไปได้ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
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) } )
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
"zara"
seq [(1, 1); (2, 4); (3, 9); (4, 16); ...]
ผู้รับมอบสิทธิ์คือตัวแปรชนิดการอ้างอิงที่เก็บการอ้างอิงถึงวิธีการ การอ้างอิงสามารถเปลี่ยนแปลงได้ที่รันไทม์ F # delegates คล้ายกับพอยน์เตอร์ของฟังก์ชันใน C หรือ C ++
การประกาศผู้รับมอบสิทธิ์
การประกาศมอบอำนาจจะกำหนดวิธีการที่ผู้รับมอบสิทธิ์สามารถอ้างถึงได้ ผู้รับมอบสิทธิ์สามารถอ้างถึงวิธีการซึ่งมีลายเซ็นเดียวกับของผู้รับมอบสิทธิ์
ไวยากรณ์สำหรับการประกาศตัวแทนคือ -
type delegate-typename = delegate of type1 -> type2
ตัวอย่างเช่นพิจารณาผู้ได้รับมอบหมาย -
// Delegate1 works with tuple arguments.
type Delegate1 = delegate of (int * int) -> int
// Delegate2 works with curried arguments.
type Delegate2 = delegate of int * int -> int
ผู้รับมอบสิทธิ์ทั้งสองสามารถใช้เพื่ออ้างอิงเมธอดใด ๆ ที่มีพารามิเตอร์intสองพารามิเตอร์และส่งกลับตัวแปรชนิดint
ในไวยากรณ์ -
type1 แสดงถึงประเภทอาร์กิวเมนต์
type2 แสดงถึงประเภทผลตอบแทน
โปรดทราบ -
ประเภทอาร์กิวเมนต์จะโค้งงอโดยอัตโนมัติ
ผู้ร่วมประชุมสามารถแนบกับค่าฟังก์ชันและวิธีการแบบคงที่หรืออินสแตนซ์
ค่าฟังก์ชัน F # สามารถส่งผ่านโดยตรงเป็นอาร์กิวเมนต์เพื่อมอบหมายผู้สร้าง
สำหรับวิธีการแบบคงที่ผู้ร่วมประชุมจะถูกเรียกโดยใช้ชื่อของคลาสและวิธีการ สำหรับวิธีการอินสแตนซ์ชื่อของอินสแตนซ์ออบเจ็กต์และเมธอดจะถูกใช้
วิธีการเรียกใช้ในประเภทผู้รับมอบสิทธิ์เรียกใช้ฟังก์ชันที่ห่อหุ้ม
นอกจากนี้ผู้รับมอบสิทธิ์สามารถส่งผ่านเป็นค่าฟังก์ชันได้โดยอ้างถึงชื่อเมธอด Invoke โดยไม่มีวงเล็บ
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
ตัวอย่าง
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)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
400 + 200 = 600
400 - 200 = 200
400 + 200 = 600
400 - 200 = 200
100 + 45 = 145
100 - 45 = 55
100 + 45 = 145
100 - 45 = 55
การแจงนับคือชุดของค่าคงที่จำนวนเต็มที่มีชื่อ
ใน F # enumerations, หรือที่เรียกว่า enums,เป็นประเภทอินทิกรัลที่เลเบลถูกกำหนดให้กับเซ็ตย่อยของค่า คุณสามารถใช้แทนตัวอักษรเพื่อทำให้โค้ดอ่านง่ายและบำรุงรักษาได้มากขึ้น
การประกาศการแจงนับ
ไวยากรณ์ทั่วไปสำหรับการประกาศการแจงนับคือ -
type enum-name =
| value1 = integer-literal1
| value2 = integer-literal2
...
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการใช้การแจงนับ -
ตัวอย่าง
// 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Monday: Mon
Saturday: Sat
Sunday: Sun
การจับคู่รูปแบบช่วยให้คุณสามารถ "เปรียบเทียบข้อมูลกับโครงสร้างเชิงตรรกะหรือโครงสร้างย่อยสลายข้อมูลเป็นส่วนที่เป็นส่วนประกอบหรือดึงข้อมูลจากข้อมูลด้วยวิธีต่างๆ"
กล่าวอีกนัยหนึ่งคือให้วิธีการทดสอบข้อมูลที่ยืดหยุ่นและมีประสิทธิภาพมากขึ้นตามเงื่อนไขต่างๆและทำการคำนวณบางอย่างตามเงื่อนไขที่เป็นไป
ตามแนวคิดแล้วมันเป็นเหมือนชุดของ if ... then
ไวยากรณ์
ในแง่ระดับสูงการจับคู่รูปแบบจะเป็นไปตามไวยากรณ์นี้ใน F # -
match expr with
| pat1 - result1
| pat2 -> result2
| pat3 when expr2 -> result3
| _ -> defaultResult
ที่ไหน
- แต่ละ | สัญลักษณ์กำหนดเงื่อนไข
- สัญลักษณ์ -> หมายถึง "ถ้าเงื่อนไขเป็นจริงให้คืนค่านี้ ... "
- สัญลักษณ์ _ เป็นรูปแบบเริ่มต้นซึ่งหมายความว่าตรงกับสิ่งอื่น ๆ ทั้งหมดเช่นสัญลักษณ์แทน
ตัวอย่าง 1
ตัวอย่างต่อไปนี้คำนวณตัวเลขฟีโบนักชีโดยใช้ไวยากรณ์การจับคู่รูปแบบ -
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)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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
คุณยังสามารถรวมเงื่อนไขหลายเงื่อนไขเข้าด้วยกันซึ่งส่งคืนค่าเดียวกัน ตัวอย่างเช่น -
ตัวอย่าง 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"
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Winter
Spring
Autumn
Rainy
ฟังก์ชันการจับคู่รูปแบบ
F # ช่วยให้คุณเขียนฟังก์ชันการจับคู่รูปแบบโดยใช้ function คีย์เวิร์ด -
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")
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
10
20.5
21
8.75
15
การเพิ่มฟิลเตอร์หรือยามให้กับรูปแบบ
คุณสามารถเพิ่มตัวกรองหรือตัวป้องกันให้กับรูปแบบโดยใช้ไฟล์ when คำสำคัญ.
ตัวอย่าง 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)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
-1
1
0
ตัวอย่าง 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)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
11 is less than 25
72 is greater than 10
0 equals 0
รูปแบบการจับคู่กับสิ่งทอ
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงรูปแบบที่ตรงกับสิ่งที่สอง -
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"))
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Hello, Zara
Hello, Raman from the department of Computer Sc.
You are not registered into the system
รูปแบบการจับคู่กับบันทึก
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการจับคู่รูปแบบกับระเบียน -
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 }
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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).
ข้อยกเว้นคือปัญหาที่เกิดขึ้นระหว่างการทำงานของโปรแกรม ข้อยกเว้น F # คือการตอบสนองต่อสถานการณ์พิเศษที่เกิดขึ้นในขณะที่โปรแกรมกำลังทำงานเช่นความพยายามที่จะหารด้วยศูนย์
ข้อยกเว้นเป็นวิธีการถ่ายโอนการควบคุมจากส่วนหนึ่งของโปรแกรมไปยังอีกส่วนหนึ่ง การจัดการข้อยกเว้น F # มีโครงสร้างต่อไปนี้ -
สร้าง | คำอธิบาย |
---|---|
เพิ่มประสบการณ์ | เพิ่มข้อยกเว้นที่กำหนด |
ล้มเหลวด้วยประสบการณ์ | เพิ่มไฟล์ System.Exception ข้อยกเว้น |
ลองใช้ expr กับกฎ | จับนิพจน์ที่ตรงกับกฎรูปแบบ |
ลอง expr ในที่สุด expr | ดำเนินการ finally นิพจน์ทั้งเมื่อการคำนวณสำเร็จและเมื่อมีการเพิ่มข้อยกเว้น |
| :? ArgumentException | กฎที่ตรงกับประเภทข้อยกเว้น. NET ที่กำหนด |
| :? ArgumentException เป็น e | กฎที่ตรงกับชนิดข้อยกเว้น. NET ที่กำหนดโดยผูกชื่อ e เป็นค่าวัตถุข้อยกเว้น |
| ความล้มเหลว (msg) → expr | กฎที่ตรงกับข้อยกเว้น F # ที่ให้ข้อมูล |
| exn → expr | กฎที่ตรงกับข้อยกเว้นใด ๆ ผูกชื่อ exn เป็นค่าวัตถุข้อยกเว้น |
| exn เมื่อ expr → expr | กฎที่ตรงกับข้อยกเว้นภายใต้เงื่อนไขที่กำหนดโดยผูกชื่อ exn เป็นค่าวัตถุข้อยกเว้น |
เริ่มต้นด้วยไวยากรณ์พื้นฐานของการจัดการข้อยกเว้น
ไวยากรณ์
ไวยากรณ์พื้นฐานสำหรับบล็อกการจัดการข้อยกเว้น F # คือ -
exception exception-type of argument-type
ที่ไหน
exception-type คือชื่อของประเภทข้อยกเว้น F # ใหม่
argument-type แสดงถึงประเภทของอาร์กิวเมนต์ที่สามารถระบุได้เมื่อคุณเพิ่มข้อยกเว้นของประเภทนี้
สามารถระบุอาร์กิวเมนต์ได้หลายรายการโดยใช้ประเภททูเพิลสำหรับประเภทอาร์กิวเมนต์
try...with นิพจน์ใช้สำหรับการจัดการข้อยกเว้นในภาษา F #
ไวยากรณ์สำหรับการลอง ... ด้วยนิพจน์คือ -
try
expression1
with
| pattern1 -> expression2
| pattern2 -> expression3
...
try...finally นิพจน์ช่วยให้คุณรันโค้ดล้างข้อมูลได้แม้ว่าบล็อกโค้ดจะมีข้อยกเว้นก็ตาม
ไวยากรณ์สำหรับการลอง ... สุดท้ายนิพจน์คือ -
try
expression1
finally
expression2
raiseฟังก์ชันใช้เพื่อระบุว่ามีข้อผิดพลาดหรือเงื่อนไขพิเศษเกิดขึ้น นอกจากนี้ยังรวบรวมข้อมูลเกี่ยวกับข้อผิดพลาดในวัตถุข้อยกเว้น
ไวยากรณ์สำหรับฟังก์ชัน Raise คือ -
raise (expression)
failwith ฟังก์ชันสร้างข้อยกเว้น F #
ไวยากรณ์สำหรับฟังก์ชัน failwith คือ -
failwith error-message-string
invalidArg ฟังก์ชันสร้างข้อยกเว้นของอาร์กิวเมนต์
invalidArg parameter-name error-message-string
ตัวอย่างการจัดการข้อยกเว้น
ตัวอย่าง 1
โปรแกรมต่อไปนี้แสดงการจัดการข้อยกเว้นพื้นฐานด้วยการลองง่ายๆ ... ด้วยบล็อก -
let divisionprog x y =
try
Some (x / y)
with
| :? System.DivideByZeroException -> printfn "Division by zero!"; None
let result1 = divisionprog 100 0
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Division by zero!
ตัวอย่าง 2
F # ให้ไฟล์ exceptionประเภทสำหรับการประกาศข้อยกเว้น คุณสามารถใช้ประเภทข้อยกเว้นได้โดยตรงในตัวกรองในไฟล์try...with นิพจน์.
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Error2 Error Not detected 100
Error1 Equal Number Error
ตัวอย่างที่ 3
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการจัดการข้อยกเว้นที่ซ้อนกัน -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
From the finally block.
Error: outer error
Error:inner error
From the finally block.
From the finally block.
Error: outer error
ตัวอย่างที่ 4
ฟังก์ชันต่อไปนี้แสดงให้เห็นถึงไฟล์ failwith ฟังก์ชัน -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Divisor cannot be zero.
0
25
ตัวอย่างที่ 5
invalidArgฟังก์ชันสร้างข้อยกเว้นของอาร์กิวเมนต์ โปรแกรมต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
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)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Sunday
Thursday
Unhandled Exception:
System.ArgumentException: You have entered 9.
…
ข้อมูลอื่น ๆ เกี่ยวกับไฟล์และตัวแปรที่ทำให้เกิดข้อผิดพลาดในระบบจะปรากฏขึ้นด้วยทั้งนี้ขึ้นอยู่กับระบบ
คลาสคือประเภทที่แสดงถึงออบเจ็กต์ที่สามารถมีคุณสมบัติวิธีการและเหตุการณ์ต่างๆ 'พวกเขาใช้เพื่อสร้างแบบจำลองการกระทำกระบวนการและเอนทิตีเชิงแนวคิดใด ๆ ในแอปพลิเคชัน'
ไวยากรณ์
ไวยากรณ์สำหรับการกำหนดประเภทคลาสมีดังนี้ -
// 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 ...
...
ที่ไหน
type-nameเป็นตัวระบุที่ถูกต้อง ตัวปรับการเข้าถึงเริ่มต้นสำหรับสิ่งนี้คือpublic.
type-params อธิบายพารามิเตอร์ประเภททั่วไปที่เป็นทางเลือก
parameter-listอธิบายพารามิเตอร์ตัวสร้าง ตัวปรับการเข้าถึงเริ่มต้นสำหรับตัวสร้างหลักคือpublic.
identifier ใช้กับอุปกรณ์เสริม as คำสำคัญตั้งชื่อให้กับตัวแปรอินสแตนซ์หรือ self-identifier, ซึ่งสามารถใช้ในการกำหนดประเภทเพื่ออ้างถึงอินสแตนซ์ของประเภท
inherit คีย์เวิร์ดช่วยให้คุณระบุคลาสพื้นฐานสำหรับคลาส
let การเชื่อมโยงช่วยให้คุณสามารถประกาศฟิลด์หรือค่าฟังก์ชันในเครื่องให้กับคลาสได้
do-bindings ส่วนประกอบด้วยรหัสที่จะดำเนินการกับการสร้างวัตถุ
member-list ประกอบด้วยตัวสร้างเพิ่มเติมอินสแตนซ์และการประกาศเมธอดแบบคงที่การประกาศอินเทอร์เฟซการเชื่อมแบบนามธรรมและการประกาศคุณสมบัติและเหตุการณ์
คำหลัก class และ end ที่ทำเครื่องหมายจุดเริ่มต้นและจุดสิ้นสุดของนิยามเป็นทางเลือก
ตัวสร้างคลาส
ตัวสร้างคือโค้ดที่สร้างอินสแตนซ์ของประเภทคลาส
ใน F # ตัวสร้างจะทำงานแตกต่างจากภาษา. Net อื่น ๆ เล็กน้อย ในนิยามคลาสอาร์กิวเมนต์ของคอนสตรัคเตอร์หลักถูกอธิบายเป็นรายการพารามิเตอร์
เนื้อหาของตัวสร้างประกอบด้วย let และ do การผูก
คุณสามารถเพิ่มตัวสร้างเพิ่มเติมได้โดยใช้คีย์เวิร์ดใหม่เพื่อเพิ่มสมาชิก -
new (argument-list) = constructor-body
ตัวอย่างต่อไปนี้แสดงแนวคิด -
ตัวอย่าง
โปรแกรมต่อไปนี้สร้างคลาสบรรทัดพร้อมกับคอนสตรัคเตอร์ที่คำนวณความยาวของบรรทัดในขณะที่สร้างอ็อบเจ็กต์ของคลาส -
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)
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Creating Line: {(1, 1), (4, 5)}
Length: 5
ให้ Bindings
การผูกแบบ let ในนิยามคลาสช่วยให้คุณกำหนดฟิลด์ส่วนตัวและฟังก์ชันส่วนตัวสำหรับคลาส 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")
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Hello Zara
โปรดสังเกตการใช้grระบุตัวเองสำหรับคลาสทักทาย
โครงสร้างใน F # คือชนิดข้อมูลประเภทค่า ช่วยให้คุณสร้างตัวแปรเดียวเก็บข้อมูลที่เกี่ยวข้องของประเภทข้อมูลต่างๆ struct คีย์เวิร์ดใช้สำหรับสร้างโครงสร้าง
ไวยากรณ์
ไวยากรณ์สำหรับการกำหนดโครงสร้างมีดังนี้ -
[ attributes ]
type [accessibility-modifier] type-name =
struct
type-definition-elements
end
// or
[ attributes ]
[<StructAttribute>]
type [accessibility-modifier] type-name =
type-definition-elements
มีสองไวยากรณ์ ส่วนใหญ่จะใช้ไวยากรณ์แรกเพราะถ้าคุณใช้struct และ end คำหลักคุณสามารถละเว้น StructAttribute แอตทริบิวต์
องค์ประกอบนิยามโครงสร้างให้ -
- คำประกาศและคำจำกัดความของสมาชิก
- ตัวสร้างและฟิลด์ที่เปลี่ยนแปลงได้และไม่เปลี่ยนรูป
- การใช้งานสมาชิกและอินเทอร์เฟซ
ไม่เหมือนคลาสโครงสร้างไม่สามารถสืบทอดและไม่สามารถมี let หรือทำการผูกได้ เนื่องจากโครงสร้างไม่อนุญาตให้มีการผูกมัด คุณต้องประกาศเขตข้อมูลในโครงสร้างโดยใช้val คำสำคัญ.
เมื่อคุณกำหนดเขตข้อมูลและประเภทโดยใช้ valคำสำคัญคุณไม่สามารถเริ่มต้นค่าฟิลด์ได้ แต่จะเริ่มต้นเป็นศูนย์หรือว่าง ดังนั้นสำหรับโครงสร้างที่มีตัวสร้างโดยนัยไฟล์val การประกาศจะใส่คำอธิบายประกอบด้วย DefaultValue แอตทริบิวต์
ตัวอย่าง
โปรแกรมต่อไปนี้สร้างโครงสร้างเส้นพร้อมกับตัวสร้าง โปรแกรมคำนวณความยาวของเส้นโดยใช้โครงสร้าง -
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Length of the Line: 5
คุณสามารถกำหนดใหม่หรือโอเวอร์โหลดตัวดำเนินการในตัวส่วนใหญ่ที่มีอยู่ใน F # ได้ ดังนั้นโปรแกรมเมอร์สามารถใช้ตัวดำเนินการกับประเภทที่ผู้ใช้กำหนดได้เช่นกัน
ตัวดำเนินการคือฟังก์ชันที่มีชื่อพิเศษอยู่ในวงเล็บ ต้องกำหนดให้เป็นสมาชิกคลาสแบบคงที่ เช่นเดียวกับฟังก์ชันอื่น ๆ ตัวดำเนินการที่โอเวอร์โหลดจะมีประเภทการส่งคืนและรายการพารามิเตอร์
ตัวอย่างต่อไปนี้แสดงตัวดำเนินการ + บนจำนวนเชิงซ้อน -
//overloading + operator
static member (+) (a : Complex, b: Complex) =
Complex(a.x + b.x, a.y + b.y)
ฟังก์ชันข้างต้นใช้ตัวดำเนินการเพิ่มเติม (+) สำหรับคลาสที่ผู้ใช้กำหนดเอง เพิ่มแอตทริบิวต์ของวัตถุสองชิ้นและส่งคืนวัตถุที่เป็นผลลัพธ์ที่ซับซ้อน
การดำเนินการของ Operator Overloading
โปรแกรมต่อไปนี้แสดงการใช้งานที่สมบูรณ์ -
//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())
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
7 5
4.2 3.1
11.2 8.1
2.8 1.9
แนวคิดที่สำคัญที่สุดอย่างหนึ่งในการเขียนโปรแกรมเชิงวัตถุคือการถ่ายทอดทางพันธุกรรม การสืบทอดช่วยให้เรากำหนดคลาสในรูปแบบของคลาสอื่นซึ่งทำให้ง่ายต่อการสร้างและดูแลแอปพลิเคชัน นอกจากนี้ยังให้โอกาสในการนำฟังก์ชันโค้ดกลับมาใช้ซ้ำและใช้งานได้รวดเร็ว
เมื่อสร้างคลาสแทนที่จะเขียนสมาชิกข้อมูลและฟังก์ชันสมาชิกใหม่ทั้งหมดโปรแกรมเมอร์สามารถกำหนดได้ว่าคลาสใหม่ควรสืบทอดสมาชิกของคลาสที่มีอยู่ คลาสที่มีอยู่นี้เรียกว่าคลาสพื้นฐานและคลาสใหม่เรียกว่าคลาสที่ได้รับ
แนวคิดเรื่องการถ่ายทอดทางพันธุกรรมดำเนินความสัมพันธ์ IS-A ตัวอย่างเช่นสัตว์เลี้ยงลูกด้วยนมเป็นสัตว์สุนัข IS-A สัตว์เลี้ยงลูกด้วยนมดังนั้นสุนัข IS-A เช่นกันและอื่น ๆ
คลาสพื้นฐานและคลาสย่อย
คลาสย่อยมาจากคลาสพื้นฐานซึ่งกำหนดไว้แล้ว คลาสย่อยจะสืบทอดสมาชิกของคลาสพื้นฐานและมีสมาชิกของตัวเอง
คลาสย่อยถูกกำหนดโดยใช้ inherit คีย์เวิร์ดตามรูปด้านล่าง -
type MyDerived(...) =
inherit MyBase(...)
ใน F # คลาสสามารถมีคลาสพื้นฐานโดยตรงได้สูงสุดหนึ่งคลาส หากคุณไม่ได้ระบุคลาสพื้นฐานโดยใช้inherit คีย์เวิร์ดคลาสโดยปริยายสืบทอดมาจาก Object
โปรดทราบ -
เมธอดและสมาชิกของคลาสพื้นฐานพร้อมใช้งานสำหรับผู้ใช้คลาสที่ได้รับเช่นสมาชิกโดยตรงของคลาสที่ได้รับ
ให้การโยงและพารามิเตอร์ตัวสร้างเป็นไพรเวตของคลาสดังนั้นจึงไม่สามารถเข้าถึงได้จากคลาสที่สืบทอดมา
คำหลัก baseหมายถึงอินสแตนซ์คลาสพื้นฐาน ใช้เหมือนตัวระบุตัวเอง
ตัวอย่าง
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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Hi, I'm Mohan
Hi, I'm Zara
Hi, I'm Mariam
วิธีการลบล้าง
คุณสามารถแทนที่พฤติกรรมเริ่มต้นของเมธอดคลาสพื้นฐานและนำไปใช้งานที่แตกต่างกันในคลาสย่อยหรือคลาสที่ได้รับ
วิธีการใน F # ไม่สามารถเขียนทับได้โดยค่าเริ่มต้น
ในการแทนที่เมธอดในคลาสที่ได้รับคุณต้องประกาศเมธอดของคุณว่าสามารถเขียนทับได้โดยใช้ abstract และ default คีย์เวิร์ดดังนี้ -
type Person(name) =
member x.Name = name
abstract Greet : unit -> unit
default x.Greet() = printfn "Hi, I'm %s" x.Name
ตอนนี้วิธีการทักทายของคลาส Person สามารถถูกแทนที่ในคลาสที่ได้รับ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
ตัวอย่าง
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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Hi, I'm Mohan
Student Zara
Teacher Mariam.
คลาสนามธรรม
ในบางครั้งคุณจำเป็นต้องจัดเตรียมการใช้งานวัตถุที่ไม่สมบูรณ์ซึ่งไม่ควรนำมาใช้ในความเป็นจริง ต่อมาโปรแกรมเมอร์คนอื่น ๆ ควรสร้างคลาสย่อยของคลาสนามธรรมเพื่อการใช้งานที่สมบูรณ์
ตัวอย่างเช่นชั้นบุคคลจะไม่จำเป็นในระบบการจัดการโรงเรียน อย่างไรก็ตามจำเป็นต้องใช้นักเรียนหรือชั้นครู ในกรณีเช่นนี้คุณสามารถประกาศคลาส Person เป็นคลาสนามธรรมได้
AbstractClass แอตทริบิวต์บอกคอมไพเลอร์ว่าคลาสมีสมาชิกนามธรรม
คุณไม่สามารถสร้างอินสแตนซ์ของคลาสนามธรรมได้เนื่องจากคลาสไม่ได้ถูกนำไปใช้อย่างสมบูรณ์
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
ตัวอย่าง
[<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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Student Zara
Teacher Mariam.
อินเทอร์เฟซเป็นวิธีที่เป็นนามธรรมในการเขียนรายละเอียดการใช้งานของคลาส เป็นเทมเพลตที่ประกาศวิธีการที่คลาสต้องใช้และเปิดเผยต่อสาธารณะ
ไวยากรณ์
อินเทอร์เฟซระบุชุดของสมาชิกที่เกี่ยวข้องซึ่งคลาสอื่น ๆ นำไปใช้ มีไวยากรณ์ต่อไปนี้ -
// 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
โปรดทราบ -
ในการประกาศอินเทอร์เฟซสมาชิกจะไม่ถูกนำไปใช้
สมาชิกเป็นนามธรรมที่ประกาศโดย abstractคำสำคัญ. อย่างไรก็ตามคุณสามารถให้การใช้งานเริ่มต้นโดยใช้ไฟล์default คำสำคัญ.
คุณสามารถใช้อินเตอร์เฟสได้โดยใช้นิพจน์อ็อบเจ็กต์หรือโดยใช้คลาสชนิด
ในการนำคลาสหรืออ็อบเจ็กต์ไปใช้งานคุณต้องจัดเตรียมเมธอดสำหรับเมธอดนามธรรมของอินเทอร์เฟซ
คำหลัก interface และ end, ซึ่งทำเครื่องหมายจุดเริ่มต้นและจุดสิ้นสุดของนิยามเป็นทางเลือก
ตัวอย่างเช่น,
type IPerson =
abstract Name : string
abstract Enter : unit -> unit
abstract Leave : unit -> unit
วิธีการโทรติดต่อ
วิธีการเชื่อมต่อถูกเรียกผ่านอินเทอร์เฟซไม่ใช่ผ่านอินสแตนซ์ของคลาสหรือประเภทการนำอินเทอร์เฟซไปใช้ ในการเรียกเมธอดอินเทอร์เฟซคุณต้องแคสต์ประเภทอินเทอร์เฟซโดยใช้:> ตัวดำเนินการ (ตัวดำเนินการ upcast)
ตัวอย่างเช่น,
(s :> IPerson).Enter()
(s :> IPerson).Leave()
ตัวอย่างต่อไปนี้แสดงแนวคิด -
ตัวอย่าง
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()
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Student entering premises!
Student leaving premises!
Stuff member entering premises!
Stuff member leaving premises!
การสืบทอดอินเทอร์เฟซ
อินเทอร์เฟซสามารถสืบทอดจากอินเทอร์เฟซพื้นฐานอย่างน้อยหนึ่งรายการ
ตัวอย่างต่อไปนี้แสดงแนวคิด -
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))
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
10
15
5
เหตุการณ์ช่วยให้ชั้นเรียนสามารถส่งและรับข้อความระหว่างกันได้
ใน GUI เหตุการณ์คือการกระทำของผู้ใช้เช่นการกดแป้นการคลิกการเคลื่อนไหวของเมาส์ ฯลฯ หรือบางเหตุการณ์เช่นการแจ้งเตือนที่ระบบสร้างขึ้น แอปพลิเคชันจำเป็นต้องตอบสนองต่อเหตุการณ์เมื่อเกิดขึ้น ตัวอย่างเช่นขัดจังหวะ เหตุการณ์ใช้สำหรับการสื่อสารระหว่างกระบวนการ
ออบเจ็กต์สื่อสารกันผ่านข้อความซิงโครนัส
กิจกรรมจะแนบไปกับฟังก์ชันอื่น ๆ ลงทะเบียนวัตถุcallback ฟังก์ชันกับเหตุการณ์และการเรียกกลับเหล่านี้จะดำเนินการเมื่อ (และถ้า) เหตุการณ์ถูกทริกเกอร์โดยวัตถุบางอย่าง
คลาสเหตุการณ์และโมดูลเหตุการณ์
คลาส Control.Event <'T> ช่วยในการสร้างวัตถุหรือเหตุการณ์ที่สังเกตได้
มีสมาชิกอินสแตนซ์ต่อไปนี้เพื่อทำงานกับเหตุการณ์ -
สมาชิก | คำอธิบาย |
---|---|
เผยแพร่ | เผยแพร่การสังเกตเป็นค่าชั้นหนึ่ง |
ทริกเกอร์ | ทริกเกอร์การสังเกตโดยใช้พารามิเตอร์ที่กำหนด |
โมดูล Control.Event จัดเตรียมฟังก์ชันสำหรับจัดการสตรีมเหตุการณ์ -
มูลค่า | คำอธิบาย |
---|---|
เพิ่ม: ('T →หน่วย) →เหตุการณ์ <' Del, 'T> →หน่วย | เรียกใช้ฟังก์ชันที่กำหนดทุกครั้งที่มีการทริกเกอร์เหตุการณ์ที่กำหนด |
เลือก: ('T →' ตัวเลือก U) → IEvent <'Del,' T> → IEvent <'U> | ส่งคืนเหตุการณ์ใหม่ที่เริ่มทำงานกับข้อความที่เลือกจากเหตุการณ์เดิม ฟังก์ชันการเลือกจะนำข้อความต้นฉบับไปยังข้อความใหม่ที่เป็นทางเลือก |
ตัวกรอง: ('T → bool) → IEvent <' Del, 'T> → IEvent <' T> | ส่งคืนเหตุการณ์ใหม่ที่รับฟังเหตุการณ์เดิมและทริกเกอร์เหตุการณ์ที่เป็นผลลัพธ์ก็ต่อเมื่ออาร์กิวเมนต์ไปยังเหตุการณ์ผ่านฟังก์ชันที่กำหนด |
แผนที่: ('T →' U) → IEvent <'Del,' T> → IEvent <'U> | ส่งคืนเหตุการณ์ใหม่ที่ส่งผ่านค่าที่เปลี่ยนโดยฟังก์ชันที่กำหนด |
ผสาน: IEvent <'Del1,' T> → IEvent <'Del2,' T> → IEvent <'T> | เริ่มต้นเหตุการณ์เอาต์พุตเมื่อเหตุการณ์อินพุตอย่างใดอย่างหนึ่งเริ่มทำงาน |
คู่: IEvent <'Del,' T> → IEvent <'T *' T> | ส่งคืนเหตุการณ์ใหม่ที่ทริกเกอร์ในเหตุการณ์อินพุตที่สองและตามมา Nth การทริกเกอร์ของเหตุการณ์อินพุตจะส่งผ่านอาร์กิวเมนต์จากไฟล์ N-1th และ Nthทริกเกอร์เป็นคู่ อาร์กิวเมนต์ส่งผ่านไปยังN-1th การทริกเกอร์จะถูกเก็บไว้ในสถานะภายในที่ซ่อนอยู่จนถึง Nth การกระตุ้นเกิดขึ้น |
พาร์ติชัน: ('T → bool) → IEvent <' Del, 'T> → IEvent <' T> * IEvent <'T> | ส่งคืนเหตุการณ์ใหม่ที่รับฟังเหตุการณ์เดิมและทริกเกอร์เหตุการณ์ที่เป็นผลลัพธ์แรกหากการประยุกต์ใช้เพรดิเคตกับอาร์กิวเมนต์เหตุการณ์ส่งคืนเป็นจริงและเหตุการณ์ที่สองหากส่งคืนเป็นเท็จ |
สแกน: ('U →' T → 'U) →' U → IEvent <'Del,' T> → IEvent <'U> | ส่งคืนเหตุการณ์ใหม่ที่ประกอบด้วยผลลัพธ์ของการใช้ฟังก์ชันการสะสมที่กำหนดกับค่าต่อเนื่องที่ทริกเกอร์ในเหตุการณ์อินพุต รายการของสถานะภายในบันทึกค่าปัจจุบันของพารามิเตอร์สถานะ สถานะภายในไม่ได้ถูกล็อกระหว่างการทำงานของฟังก์ชันการสะสมดังนั้นควรใช้ความระมัดระวังว่า IEvent อินพุตจะไม่ถูกทริกเกอร์โดยเธรดหลายเธรดพร้อมกัน |
แยก: ('T →ทางเลือก <' U1, 'U2>) → IEvent <' Del, 'T> → IEvent <' U1> * IEvent <'U2> | ส่งคืนเหตุการณ์ใหม่ที่รับฟังเหตุการณ์ดั้งเดิมและทริกเกอร์เหตุการณ์ที่เป็นผลลัพธ์แรกหากการประยุกต์ใช้ฟังก์ชันกับอาร์กิวเมนต์เหตุการณ์ส่งคืน Choice1Of2 และเหตุการณ์ที่สองหากส่งคืน Choice2Of2 |
การสร้างกิจกรรม
กิจกรรมถูกสร้างและใช้ผ่านไฟล์ Eventชั้นเรียน. ตัวสร้างเหตุการณ์ใช้สำหรับสร้างเหตุการณ์
ตัวอย่าง
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
หลังจากนี้คุณจะต้องเปิดเผยฟิลด์ nameChanged ในฐานะสมาชิกสาธารณะเพื่อให้ผู้ฟังสามารถเชื่อมต่อกับเหตุการณ์ที่คุณใช้ Publish ทรัพย์สินของงาน -
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 *)
จากนั้นคุณจะเพิ่มการเรียกกลับไปยังตัวจัดการเหตุการณ์ ตัวจัดการเหตุการณ์แต่ละตัวมีประเภท IEvent <'T> ซึ่งมีหลายวิธี -
วิธี | คำอธิบาย |
---|---|
val เพิ่ม: เหตุการณ์ :( 'T →หน่วย) →หน่วย | เชื่อมต่อฟังก์ชันผู้ฟังกับเหตุการณ์ ผู้ฟังจะถูกเรียกเมื่อเหตุการณ์เริ่มทำงาน |
val AddHandler: 'del →หน่วย | เชื่อมต่ออ็อบเจ็กต์ผู้รับมอบสิทธิ์ตัวจัดการกับเหตุการณ์ ตัวจัดการสามารถลบออกได้ในภายหลังโดยใช้ RemoveHandler ผู้ฟังจะถูกเรียกเมื่อเหตุการณ์เริ่มทำงาน |
Val RemoveHandler: 'del → unit | ลบผู้ร่วมประชุมออกจากที่เก็บตัวฟังเหตุการณ์ |
ส่วนต่อไปนี้เป็นตัวอย่างที่สมบูรณ์
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิดและเทคนิคที่กล่าวถึงข้างต้น -
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"
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
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!
ตามไลบรารี MSDN โมดูล F # คือการจัดกลุ่มโครงสร้างรหัส F # เช่นประเภทค่าค่าฟังก์ชันและรหัสในการเชื่อมโยง มันถูกนำไปใช้เป็นคลาสรันไทม์ภาษาทั่วไป (CLR) ที่มีสมาชิกแบบคงที่เท่านั้น
ขึ้นอยู่กับสถานการณ์ว่าไฟล์ทั้งหมดรวมอยู่ในโมดูลหรือไม่มีการประกาศโมดูลสองประเภท -
- การประกาศโมดูลระดับบนสุด
- การประกาศโมดูลภายใน
ในการประกาศโมดูลระดับบนสุดไฟล์ทั้งหมดจะรวมอยู่ในโมดูล ในกรณีนี้การประกาศครั้งแรกในไฟล์คือการประกาศโมดูล คุณไม่จำเป็นต้องเยื้องการประกาศในโมดูลระดับบนสุด
ในการประกาศโมดูลโลคัลเฉพาะการประกาศที่เยื้องภายใต้การประกาศโมดูลนั้นเท่านั้นที่เป็นส่วนหนึ่งของโมดูล
ไวยากรณ์
ไวยากรณ์สำหรับการประกาศโมดูลมีดังนี้ -
// Top-level module declaration.
module [accessibility-modifier] [qualified-namespace.]module-name
declarations
// Local module declaration.
module [accessibility-modifier] module-name =
declarations
โปรดทราบว่าตัวปรับแต่งการช่วยการเข้าถึงสามารถเป็นอย่างใดอย่างหนึ่งต่อไปนี้ - สาธารณะส่วนตัวภายใน ค่าเริ่มต้นคือpublic.
ตัวอย่างต่อไปนี้จะแสดงให้เห็นถึงแนวคิด -
ตัวอย่าง 1
ไฟล์โมดูล 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
ไฟล์โปรแกรม 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
34
16
225
2
110
90
1000
10
ตัวอย่าง 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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
125
325
ก namespaceได้รับการออกแบบมาเพื่อจัดเตรียมวิธีการแยกชื่อชุดหนึ่งจากชื่ออื่น ชื่อคลาสที่ประกาศในเนมสเปซเดียวจะไม่ขัดแย้งกับชื่อคลาสเดียวกันที่ประกาศในอีกชื่อหนึ่ง
ตามไลบรารี MSDN ก namespace ช่วยให้คุณสามารถจัดระเบียบรหัสเป็นส่วนต่างๆของฟังก์ชันการทำงานที่เกี่ยวข้องโดยให้คุณแนบชื่อเข้ากับการจัดกลุ่มองค์ประกอบของโปรแกรม
การประกาศ Namespace
ในการจัดระเบียบรหัสของคุณในเนมสเปซคุณต้องประกาศเนมสเปซเป็นการประกาศครั้งแรกในไฟล์ เนื้อหาของไฟล์ทั้งหมดจะกลายเป็นส่วนหนึ่งของเนมสเปซ
namespace [parent-namespaces.]identifier
ตัวอย่างต่อไปนี้แสดงแนวคิด -
ตัวอย่าง
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
เมื่อคุณคอมไพล์และรันโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Values from Module1: ("one", "two", "three") 150
Values from Module2: seq [1; 4; 9; 16; ...] 200