- F# 基础教程
- F# - 主页
- F# - 概述
- F# - 环境设置
- F# - 程序结构
- F# - 基本语法
- F# - 数据类型
- F# - 变量
- F# - 运算符
- F# - 决策
- F# - 循环
- F# - 函数
- F# - 字符串
- F# - 选项
- F# - 元组
- F# - 记录
- F# - 列表
- F# - 序列
- F# - 集
- F# - 地图
- F# - 受歧视的工会
- F# - 可变数据
- F# - 数组
- F# - 可变列表
- F# - 可变字典
- F# - 基本 I/O
- F# - 泛型
- F# - 代表
- F# - 枚举
- F# - 模式匹配
- F# - 异常处理
- F# - 类
- F# - 结构
- F# - 运算符重载
- F# - 继承
- F# - 接口
- F# - 事件
- F# - 模块
- F# - 命名空间
- F# 有用资源
- F# - 快速指南
- F# - 有用的资源
- F# - 讨论
F# - 函数
在 F# 中,函数的工作方式类似于数据类型。您可以像任何其他变量一样声明和使用函数。
由于函数可以像任何其他变量一样使用,因此您可以 -
- 创建一个具有名称的函数,并将该名称与类型相关联。
- 为其指定一个值。
- 对该值进行一些计算。
- 将其作为参数传递给另一个函数或子例程。
- 将一个函数作为另一个函数的结果返回。
定义函数
函数是使用let关键字定义的。函数定义具有以下语法 -
let [inline] function-name parameter-list [ : return-type ] = function-body
在哪里,
function-name是代表函数的标识符。
参数列表给出以空格分隔的参数列表。您还可以为每个参数指定显式类型,如果未指定,编译器往往会从函数体(如变量)中推断出它。
函数体由一个表达式或由多个表达式组成的复合表达式组成。函数体中的最后一个表达式是返回值。
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 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
当您编译并执行该程序时,它会产生以下输出 -
Volume: 141.372
实施例2
以下程序返回两个给定参数中较大的值 -
// 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
当您编译并执行该程序时,它会产生以下输出 -
Max Value: 52
实施例3
let doubleIt (x : int) = 2 * x printfn "Double 19: %d" ( doubleIt(19))
当您编译并执行该程序时,它会产生以下输出 -
Double 19: 38
递归函数
递归函数是调用自身的函数。
您可以使用let rec关键字组合定义递归。
定义递归函数的语法是 -
//Recursive function definition let 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: 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
实施例2
以下程序返回阶乘 8 -
open System let 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。 |
整型 → 字符串 → 浮点数 | 该函数接受一个int和一个字符串输入,返回一个float。 |
拉姆达表达式
lambda表达式是一个未命名的函数。
让我们举两个函数的例子 -
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
当您编译并执行该程序时,它会产生以下输出 -
35
在上面的例子中,如果我们不定义函数mul,而是使用 lambda 表达式:
let applyFunction ( f: int -> int -> int) x y = f x y let res = applyFunction (fun x y -> x * y ) 5 7 printfn "%d" res
当您编译并执行该程序时,它会产生以下输出 -
35
函数组合和流水线
在 F# 中,一个函数可以由其他函数组成。
以下示例显示了由两个函数 function1 和 function2 组成的名为 f 的函数的组成 -
let function1 x = x + 1 let function2 x = x * 5 let f = function1 >> function2 let res = f 10 printfn "%d" res
当您编译并执行该程序时,它会产生以下输出 -
55
F# 还提供了一种称为函数流水线的功能。流水线允许函数调用作为连续操作链接在一起。
以下示例表明 -
let function1 x = x + 1 let function2 x = x * 5 let res = 10 |> function1 |> function2 printfn "%d" res
当您编译并执行该程序时,它会产生以下输出 -
55