F# - 泛型

泛型允许您延迟指定类或方法中编程元素的数据类型,直到在程序中实际使用它为止。 换句话说,泛型允许您编写可以处理任何数据类型的类或方法。

您编写类或方法的规范,并使用数据类型的替代参数。 当编译器遇到类的构造函数或方法的函数调用时,它会生成处理特定数据类型的代码。

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