本文包含以下内容
1.函数含有可变参数的使用情况
定义含有可变参数的函数
函数接收可变参数后进行解包操作并使用
2.函数作为另一个函数的参数
也称为回调函数
函数作为参数意味着可以在程序运行时决定具体的调用情况
意识到函数本身是一个变量 可以进行赋值
函数的签名取决于参数个数以及类型以及返回值的个数以及类型
3.匿名函数的使用
定义或者使用匿名函数 可以简化我们的代码
4.函数的闭包
可以在程序运行时 根据提供的参数创建不同的函数
代码演示+详细注释
package main
import "fmt"
func add(a, b int, args ...int) int {
fmt.Printf("%T %T %T\n", a, b, args)
sum := 0
sum += a + b
//add函数会得到一个args切片
for _, v := range args {
sum += v
}
return sum
}
func calculate(op string, a, b int, args ...int) int {
switch op {
case "add":
//对可变参数args进行解包操作 加上...
//解包后从整数切片类型变成了整数类型
return add(a, b, args...)
default:
return -1
}
}
func fun0(str string) int {
fmt.Println("this is", str)
return -1
}
//callback是格式化函数 指定打印的不同格式
//printFormat函数有两个参数 没有返回值
//这种情况下 函数作为参数 意味着可以在运行时决定具体的调用情况
//即在printFormat中调用callback函数
//第一个是有可变参数的回调函数
//第二个是字符串类型的可变参数
func printFormat(callback func(...string), args ...string) {
//解包args 从切片变成一组元素
callback(args...)
}
//list函数的签名和上方的callback函数一致
func list(args ...string) {
for i, v := range args {
fmt.Println(i, ":", v)
}
}
func main() {
//函数的可变参数 一个函数只能接收一个类型一致的可变参数
fmt.Println(add(1, 2))
fmt.Println(calculate("add", 1, 2, 3, 4, 5))
//对切边解包后调用
args := []int{3, 4, 5}
fmt.Println(calculate("add", 1, 2, args...))
//在Go语言中 函数的签名由参数和返回值的详细内容决定
fmt.Println(fun0("lh"))
var fun1 func(string) int = fun0
fmt.Println(fun1("lh"))
fmt.Printf("fun0:%T\n", fun0)
fmt.Printf("fun1:%T\n", fun1)
printFormat(list, "A", "B", "C")
//定义匿名函数后使用
sayHello := func(name string) {
fmt.Println("Hello", name)
}
sayHello("zpz")
//匿名函数的直接调用
func(name string) {
fmt.Println("Hi", name)
}("lh")
printFormat(func(args ...string) {
for _, v := range args {
fmt.Printf("%s\t", v)
}
fmt.Println()
}, "1", "2", "3")
//闭包 函数作为返回值
add2 := func(n int) int {
return n + 2
}
add5 := func(n int) int {
return n + 5
}
add10 := func(n int) int {
return n + 10
}
fmt.Println(add2(1))
fmt.Println(add5(1))
fmt.Println(add10(1))
//在语句块内可以使用语句块外(之前)的变量
//定义闭包
addBase := func(base int) func(int) int {
return func(n int) int {
return base + n
}
}
//使用闭包
add100 := addBase(100)
fmt.Println(add100(1))
fmt.Println(addBase(500)(20))
}