函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码段,其可以提高应用的模块性和代码的重复利用率。函数是Go语言程序重要的构成部分之一,通过编写函数和对函数的调用可以实现软件项目需要的功能。在Go语言软件项目中,绝大多数功能是通过函数实现的。在本章的内容中,将详细讲解Go语言函数的知识,并通过具体实例讲解使用函数的方法。
5.1 函数基础
在Go语言中,函数是为了实现某个功能而编写的。要实现不同的功能,可以提前编写好对应的函数。例如在本书前面实例中多次用到的Printf()就是一个函数,它是Go语言官方提供的内置库函数。
5.1.1 声明函数
在Go程序中,函数的声明通常包括函数名、参数列表、返回值列表和函数体。声明函数的语法格式如下所示。
func 函数名(参数列表) (返回值列表) {
函数体
}
对上述格式的具体说明如下所示:
- 函数名:是标识符,用于表示函数的名称。
- 参数列表:是函数的输入参数,可以是零个或多个参数,每个参数包括参数名和参数类型,多个参数之间使用逗号分隔。
- 返回值列表:是函数的返回值,可以是零个或多个返回值,每个返回值包括返回值类型,多个返回值之间使用逗号分隔。
- 函数体:是函数的具体实现代码,可以包含一系列语句,完成具体的功能。函数体可以包含任意数量的语句,使用大括号括起来表示一个代码块。函数体中的语句按照顺序依次执行,直到函数结束或遇到 return 语句返回结果。
例如,下面是一个简单的函数声明示例,该函数的功能是将两个整数相加并返回结果。
func add(x int, y int) int {
return x + y
}
在上述代码中,函数名为 add,参数列表包含两个整数参数 x 和 y,返回值列表包含一个整数类型的返回值,函数体包含一条 return 语句,将两个整数相加并返回结果。
5.1.2 函数的返回值
在 Go 语言中,函数可以返回一个或多个返回值,返回值由一个或多个值组成的列表表示。函数的返回值列表在函数声明中定义,并且可以是任意数量的,也可以是没有返回值的。
(1)有一个返回值
如果函数有一个返回值,可以使用 return 语句返回一个值。例如:
func sum(x int, y int) int {
return x + y
}
(2)有多个返回值
如果函数有多个返回值,则可以使用逗号分隔它们,例如:
func swap(x, y string) (string, string) {
return y, x
}
这样在调用上述有多个返回值的函数时,可以使用多个变量接收多个返回值:
a, b := swap("hello", "world")
fmt.Println(a, b) // 输出:world hello
(3)没有返回值
如果函数没有返回值,则返回类型列表为空,例如:
func printHello() {
fmt.Println("Hello")
}
在函数体内,如果使用 return 语句而不带参数,则函数会立即返回并且不会返回任何值。在函数体内使用 return 语句时,也可以指定返回值,例如在下面的代码中,如果除数 y 为 0,则返回错误信息。如果 y 不为 0,则返回除法结果和一个 nil 错误值。
func divide(x float64, y float64) (float64, error) {
if y == 0 {
return 0, errors.New("division by zero")
}
return x / y, nil
}
注意:函数的返回值在 Go 语言中非常灵活,可以返回任意数量的值,也可以返回错误信息等特殊类型。理解函数的返回值,对于编写高效、易读、易于维护的代码非常重要。
5.1.3 调用函数
函数是为了实现某些功能而编写,那么该如何使用函数呢,这就是函数调用。函数调用是指在程序中使用函数的过程,它可以通过函数名和参数列表来调用函数。在Go语言中,函数的调用非常简单,只需要使用函数名和括号将参数列表括起来即可。例如有一个名为 add()的函数,功能是接收两个整数并返回它们的和,函数add()的代码如下。
func add(a, b int) int {
return a + b
}
接下来可以在程序中调用上面的函数add(),并将计算结果存储在变量sum中。例如在下面的代码中,调用函数add()并将 3 和 5 作为参数传递给它。执行函数add()后返回 8,这个值被存储在变量sum中,并最终被打印出来。
sum := add(3, 5)
fmt.Println(sum) // Output: 8
需要注意的是,如果函数有多个返回值,我们可以使用多个变量来接收它们,例如在线的代码中, 函数calculate()接收两个整数并返回它们的和与差。在调用函数时使用两个变量 sum 和 diff 来接收这两个返回值,然后将它们打印出来。
func calculate(a, b int) (int, int) {
sum := a + b
difference := a - b
return sum, difference
}
sum, diff := calculate(10, 5)
fmt.Println(sum, diff) // Output: 15 5
实例5-1:个税计算器(源码路径:Go-codes\5\tax.go)
假设某国政府规定,个人所得税的税率如表5-1所示。
表5-1 个人所得税的税率表
级数 | 全月应纳税所得额(元) | 税率 |
1 | 不超过5000元 | 0% |
2 | 超过5000元至8000元,包括8000元 | 3% |
3 | 超过8000元至17000元,包括17000元 | 10% |
4 | 超过17000元至30000元,包括30000元 | 20% |
5 | 超过30000元至40000元,包括40000元 | 25% |
6 | 超过40000元至60000元,包括60000元 | 30% |
7 | 超过60000元至85000元,包括85000元 | 35% |
8 | 超过85000元 | 45% |
假设某人的收入是50000元,请编写程序计算他应该缴纳的个税。
实例文件tax.go的具体实现代码如下所示。
package main
import "fmt"
func calculateTax(income float64) float64 {
var tax float64
if income <= 5000 {
tax = 0
} else if income > 5000 && income <= 8000 {
tax = (income - 5000) * 0.03
} else if income > 8000 && income <= 17000 {
tax = (income - 8000) * 0.1 + 9000 * 0.03
} else if income > 17000 && income <= 30000 {
tax = (income - 17000) * 0.2 + 9000 * 0.03 + 9000 * 0.1
} else if income > 30000 && income <= 40000 {
tax = (income - 30000) * 0.25 + 9000 * 0.03 + 9000 * 0.1 + 13000 * 0.2
} else if income > 40000 && income <= 60000 {
tax = (income - 40000) * 0.3 + 9000 * 0.03 + 9000 * 0.1 + 13000 * 0.2 + 10000 * 0.25
} else if income > 60000 && income <= 85000 {
tax = (income - 60000) * 0.35 + 9000 * 0.03 + 9000 * 0.1 + 13000 * 0.2 + 10000 * 0.25 + 20000 * 0.3
} else {
tax = (income - 85000) * 0.45 + 9000 * 0.03 + 9000 * 0.1 + 13000 * 0.2 + 10000 * 0.25 + 20000 * 0.3 + 25000 * 0.35
}
return tax
}
func main() {
income := 50000.0
tax := calculateTax(income)
fmt.Printf("Income: %.2f, Tax: %.2f\n", income, tax)
}
在上述代码中定义了函数calculateTax(),用于计算个人所得税,函数的输入参数是收入金额,返回值是税金金额。在主函数中调用函数calculateTax(),并输出结果。在这个例子中,如果输入收入为 50000 元,则计算得到的个人所得税为 11450 元。执行后会输出:
Income: 50000.00, Tax: 9270.00
5.1.4 函数变量
在Go语言中,函数也可以像普通变量一样被赋值、传递和使用,称之为函数变量。函数变量可以看做是一个变量名,其类型是一个函数类型。通过函数变量,可以将函数作为参数传递给其他函数,也可以将函数作为返回值返回给调用者。
定义函数变量的方式和定义普通变量类似,只需要使用关键字func定义函数类型即可。例如在下面的例子中,定义了一个函数类型 IntFunc,然后声明了一个函数变量 addOne,其类型为 IntFunc。我们将一个匿名函数赋值给 addOne,该函数接收一个 int 类型的参数并返回其加 1 后的结果。最后,我们调用了函数变量 addOne,将参数 1 传入并获取结果 2。
// 定义一个函数类型 func(int) int
type IntFunc func(int) int
// 声明一个函数变量,类型为 IntFunc
var addOne IntFunc = func(x int) int {
return x + 1
}
// 使用函数变量
result := addOne(1) // result 等于 2
在Go语言中,通过使用函数变量,我们可以方便地实现一些高级特性,例如函数闭包、函数回调等。
实例5-2:四则运算计算器(源码路径:Go-codes\5\caca.go)
实例文件caca.go的具体实现代码如下所示。
package main
import "fmt"
// 定义一个函数类型
type operation func(int, int) int
// 定义四个基本运算函数
func add(a, b int) int {
return a + b
}
func subtract(a, b int) int {
return a - b
}
func multiply(a, b int) int {
return a * b
}
func divide(a, b int) int {
return a / b
}
// 定义一个高阶函数,接收两个 int 类型的参数和一个 operation 类型的函数变量
// 返回两个参数进行操作后的结果
func calculate(a, b int, op operation) int {
return op(a, b)
}
func main() {
// 使用函数变量 add 进行计算
result := calculate(5, 3, add)
fmt.Println(result) // 输出:8
// 使用函数变量 subtract 进行计算
result = calculate(5, 3, subtract)
fmt.Println(result) // 输出:2
// 使用函数变量 multiply 进行计算
result = calculate(5, 3, multiply)
fmt.Println(result) // 输出:15
// 使用函数变量 divide 进行计算
result = calculate(5, 3, divide)
fmt.Println(result) // 输出:1
}
对上述代码的具体说明如下所示:
- 首先,定义了一个函数类型 operation,表示对两个 int 类型的操作并返回一个 int 类型的结果。接着,我们定义了四个基本运算函数 add()、subtract()、multiply()和 divide(),并分别实现了加、减、乘和除四种运算操作。
- 然后,定义了一个高阶函数 calculate(),该函数接收两个 int 类型的参数和一个 operation 类型的函数变量,并返回两个参数进行操作后的结果。最后,我们在 main 函数中使用了不同的函数变量进行计算,输出了计算结果。
执行后会输出:
8
2
15
1