函数
与 C++ 相比,Golang 的函数编程更加的方便简洁。
Golang 具体的函数定义和函数用法如下例所示:
go
package main
import (
"fmt"
"math"
"reflect"
"runtime"
)
func div(a, b int) (int, int) { // Golang 的函数可以有多个返回值
return a / b, a % b
}
func eval(a, b int, op string) (int, error) {
switch op {
case "+":
return a + b, nil
case "-":
return a - b, nil
case "*":
return a * b, nil
case "/":
q, _ := div(a, b)
return q, nil
default:
return 0, fmt.Errorf("unsupported operation: " + op)
}
}
func apply(op func(int, int) int, a, b int) int { // Golang 函数的参数可以是一个函数
p := reflect.ValueOf(op).Pointer()
opName := runtime.FuncForPC(p).Name()
fmt.Printf("Calling function %s with args "+"(%d, %d)\n", opName, a, b)
return op(a, b)
}
func pow(a, b int) int { // 回顾之前的内容, Golang 不支持任何隐式类型转换
return int(math.Pow(float64(a), float64(b))) // 因此必须使用显式类型转换
}
func sum(numbers ...int) int { // Golang 的函数不支持默认参数或可选参数
s := 0 // 但 Golang 的函数支持可变数量的参数, 如本例所示
for i := range numbers {
s += numbers[i]
}
return s
}
func main() {
if result, err := eval(3, 4, "+"); err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}
fmt.Println(apply(pow, 3, 4)) // 函数的参数也可以是一个函数
// 👆 函数式编程
fmt.Println(
apply(func(a, b int) int {
return int(math.Pow(float64(a), float64(b)))
}, 3, 4)) // 可以直接通过匿名函数的方式将函数传递给
// 与 C++ 11 新增的 lambda 表达式相比, Golang 的 lambda 表达式不要太简洁
fmt.Println(sum(1, 2, 3, 4, 5)) // 可变参数列表
/*
Golang 函数语法要点回顾
- 返回值类型写在最后面;
- 可以返回多个值;
- 函数可以作为参数(支持函数式编程)
- 没有默认参数/可选参数
*/
}
Golang 函数的要点总结如下:
- 与变量的定义类似,Golang 的函数定义是函数名称在前,返回值类型(或具体的返回值!)在后;
- Golang 当中的函数可以有多个返回值;
- Golang 函数的参数可以是一个函数,这个实参可以是 lambda 表达式。与 C++ 11 当中的 lambda 表达式相比,Golang 当中的 lambda 表达式非常的简洁,可以把它看作是一个局部的函数定义,不需要额外的声明;
- Golang 的函数不支持默认参数或可选参数,但支持可变形参数量的参数,可变形参数量的参数相当于将传入的实参列表封装为一个数组,在函数定义当中可以使用 for 对形参进行遍历。