F # - Generics

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); ...]