3.1.2 函数声明

3.1.2 函数声明

 

    正如前面提到的,我们可以使用 let 绑定声明函数。让我们在一个相当简单的函数上来演示,用两个给定参数值相乘。在 F# Interactive 中输入:

 

> let multiply num1 num2 =
num1 * num2;;
val multiply : int -> int –> int

 

    要写一个函数声明,符号名的后面必须跟一个或更多参数的名字。在这个示例中,我们写的函数有两个参数,因此,函数名 (multiply)的后跟两个参数 (num1 和 num2)。现在,让我们看一下函数体。我们可以把函数体简单地看成绑定到这个符号的表达式,表示这个函数的名字(这里,multiply),区别在于,这个符号并不代表一个简单的值,而是代表带几个参数值的函数。

    在第 2 章,我们学习了 F# 中的函数也是值。这意味着,当使用 let 结构,我们总是创建一个值,但如果我们指定参数值,就声明了一种特殊类型的值:函数。从严格的数学角度来看,一个普通的值是一个没有任何参数值的函数,F# 语法上散发出更多的光。如果在函数声明中的省略所有的参数值,将得到一个简单的值的声明。

    当编写函数时,务必正确缩进函数体。这样,不必使用其他、更明确的方式来指定函数声明的结束,就像使用 OCaml-compatible 语法一样。

 

函数签名

 

    前面示例中,我们还有一部分尚未讨论的是,由 F# Interactive 打印的输出,它报告了我们声明的新值和推导出的类型。因为,我们声明了一个函数,它的类型是函数类型,写作 int-> int-> int。这个类表示一个函数有两个 int 类型的参数值(在最后的箭头符号前两个 int), 返回 int 类型(这个类型最后的箭头符号) 的结果。我们已经看到 F# 使用类型推断推导出这个类型,在这个示例中,F# 用默认类型进行数值计算(整数)。我们将在第 5 章回到函数类型,再解释为什么参数分隔符号与返回值中使用的相同。

 

嵌套函数声明

 

    让我们现在看一下稍微复杂的函数声明,在清单 3.3 中,也演示了 let 绑定的另一个有趣的方面:可以嵌套这一事实。

 

Listing 3.3 Nested let bindings (F# Interactive)

 

> let printSquares message num1 num2 =
let printSquareUtility num =
let squared = num * num
printfn "%s %d: %d" message num squared
printSquareUtility(num1)
printSquareUtility(num2)
;;
val printSquares : string -> int -> int –> unit
 

> printSquares "Square of" 14 27;;
Square of 14: 196
Square of 27: 729

 

    清单 3.3 显示了一个名为 printSquares 的函数的实现。正如你可以从其签名 ((string -> int -> int -> unit)中看到的,这个函数取一个 string 作为第一个参数值(message),两个数字 (num1 和 num2)作为第二、三个参数值,该函数打印最后两个参数值的平方,用第一个参数值设置输出格式。它不返回任何值,因此,函数返回类型是 unit。

    PrintSquares 函数的主体包含嵌套声明的 printSquareUtility 函数。这个工具函数取一个数字作为参数值,计算其平方,连同原来的数字一起打印。其主体包含不至一个嵌套 let 绑定,声明一个普通值,squared,此值被赋给参数值的平方,使代码更具可读性。工具函数最后用 printfn 调用输出message、原来的数字,和这个数的平方。第一个参数指定参数值的格式和类型(%s 代表字符串, %d 代表整数)。

    有关嵌套声明的一个更重要方面可用这个示例来演示。我们已经提到,一个函数的参数的范围(意思是它们可以被访问)在函数体的任意位置。例如,在整个范围内,参数 message 可以用在任意地方,这也意味着,可以用在嵌套的函数声明,而这正是我们在第四行printSquareUtility 所做的,在我们用 message 值输出数字时。当然,嵌套声明只在声明它们的范围内才可访问——例如,你不能直接从程序的其他地方使用 printSquareUtility。正确的值范围也保证了 message 参数总是会有一个值。

    在 F# 中,值声明的最后一个方面是,可用于声明可变值。虽然,我们在函数程序中,通常使用不可变的值,但有时,能够创建一个可变的值,也很有用。

你可能感兴趣的:(C#,职场,F#,休闲,函数编程)