在F#中,函数的工作方式与数据类型相同.你可以像任何其他变量一样声明和使用函数.
由于函数可以像任何其他变量一样使用,你可以&减去;
创建一个带有名称并将该名称与类型相关联的函数.
为其赋值.
对该值执行一些计算.
将其作为参数传递给另一个函数或子例程.
返回a函数作为另一个函数的结果.
定义函数
使用定义函数让关键字.函数定义具有以下语法 :
let [inline] function-name parameter-list [:return-type] = function-body
其中,
function-name 是表示该功能的标识符.
参数列表给出列表由空格分隔的参数.您还可以为每个参数指定显式类型,如果未指定,编译器倾向于从函数体中推导出它(如变量).
函数-body 由表达式或由多个表达式组成的复合表达式组成.函数体中的最终表达式是返回值.
return-type 是一个冒号后跟一个类型,是可选的.如果未指定返回类型,则编译器从函数体中的最终表达式确定它.
函数的参数
您可以在函数名称后面列出参数的名称.您可以指定参数的类型.参数的类型应遵循以冒号分隔的参数名称.
如果未指定参数类型,则由编译器推断.
例如 :
let doubleIt (x : int) = 2 * x
调用函数
通过指定函数名后跟空格然后用空格分隔的任何参数来调用函数.
例如 :
let vol = cylinderVolume 3.0 5.0
以下程序说明了这些概念.
示例1
以下程序计算半径和长度给定时的圆柱体积参数
// the function calculates the volume of// a cylinder with radius and length as parameterslet cylinderVolume radius length : float = // function body let pi = 3.14159 length * pi * radius * radiuslet vol = cylinderVolume 3.0 5.0printfn " Volume: %g " vol
编译并执行程序时,它会产生以下输出 :
Volume: 141.372
示例2
以下程序返回两个给定参数的较大值 :
// the function returns the larger value between two// argumentslet max num1 num2 : int32 = // function body if(num1>num2)then num1 else num2let res = max 39 52printfn " Max Value: %d " res
编译并执行程序时,会产生以下输出和减号;
Max Value: 52
示例3
let doubleIt (x : int) = 2 * xprintfn "Double 19: %d" ( doubleIt(19))
当你编译并执行程序时,它产生以下输出 :
Double 19: 38
递归函数
递归函数是自称的函数.
使用 let rec 关键字组合定义递归.
定义递归函数的语法是 :
//Recursive function definitionlet rec function-name parameter-list = recursive-function-body
例如 :
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
示例1
以下程序返回Fibonacci 1到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)
编译并执行程序时,它会产生以下输出 :
Fibonacci 1: 1Fibonacci 2: 2Fibonacci 3: 3Fibonacci 4: 5Fibonacci 5: 8Fibonacci 6: 13Fibonacci 7: 21Fibonacci 8: 34Fibonacci 9: 55Fibonacci 10: 89
示例2
以下程序返回factorial 8 :
open Systemlet rec fact x = if x < 1 then 1 else x * fact (x - 1)Console.WriteLine(fact 8)
编译和执行时该程序,它产生以下输出 :
40320
F#中的箭头符号
F#使用链式箭头表示法报告函数和值中的数据类型.让我们举一个函数的例子,它接受一个 int 输入,并返回一个字符串.在箭头符号中,它写为 :
int -> string
从左到右读取数据类型.
让我们采用另一个带有两个int数据的假设函数输入并返回一个字符串.
let mydivfunction x y = (x / y).ToString();;
F#使用链式箭头符号报告数据类型为 :
val mydivfunction : x:int -> y:int -> string
返回类型由链式箭头表示法中最右边的数据类型表示.
更多示例 :
符号 | 含义 |
---|---|
float → float → float | 该函数接受两个 float 输入,返回另一个 float . |
int → string → float | 该函数接受 int 和 string 输入,返回 float . |
Lambda表达式
lambda表达式是一个未命名的函数.
让我们举两个函数的例子 :
let applyFunction ( f: int -> int -> int) x y = f x ylet mul x y = x * ylet res = applyFunction mul 5 7printfn "%d" res
编译并执行程序时,它会产生以下输出 :
35
现在在上面的例子中,如果不是定义函数 mul,我们可能有使用lambda表达式为 :
let applyFunction ( f: int -> int -> int) x y = f x ylet res = applyFunction (fun x y -> x * y ) 5 7printfn "%d" res
编译并执行程序时,它会产生以下输出 :
35
函数组合和流水线
在F#中,一个函数可以由其他函数组成.
以下示例显示一个名为f的函数的组成,来自两个函数function1和function2 :
let function1 x = x + 1let function2 x = x * 5let f = function1 >> function2let res = f 10printfn "%d" res
当你编译并执行程序时,它产生以下结果输出&减去;
55
F#还提供了一个名为函数的流水线操作.流水线操作允许函数调用作为连续操作链接在一起.
以下示例显示 :
let function1 x = x + 1let function2 x = x * 5let res = 10 |> function1 |> function2printfn "%d" res
编译并执行程序时,它会产生以下输出 :
55