一、函数基础
函数用于对代码块的逻辑封装,提供代码复用的最基本方式。使用func关键字声明函数,其次是函数名,形参,返回值,函数体,形参和返回值如果没有可以省略。使用return关键字返回值。
示例1:无参数,无返回值
func helloWorld() {
fmt.Println("Hello World")
}
helloWorld()
示例2:单个形参
func sayHi(user string) {
fmt.Println("Hi", user)
}
sayHi()
示例3:多个形参(类型合并)
多个形参类型一致可只保留最后一个类型,形参可以不使用
func sayHi(stu1,stu2 string, b1 bool){
fmt.Println("Hi",stu1)
fmt.Println("Hi",stu2)
}
sayHi("alex","eric",false)
示例4:形参可变
可变参数只能定义一个,且只能在参数列表的最后,被调用时,可变参数被初始化为对应类型的切片
func varArgs(args ...string){
fmt.Println(args)
}
varArgs("11","22","33") //调用可变参数
varArgs([]string{"11","22","33"}...) //切片解包后传递给可变参数函数
示例5:有参数,有返回值
返回值可指定变量名,变量在调用时会根据类型使用零值进行初始化,
func add(n1,n2 int) (sum int){
return n1 + n2
}
sum := add(1,2)
fmt.Println(sum)
在调用 return时不需要添加返回值,go语言自动将变量的最终结果进行返回
在使用命名返回值时,当声明函数中存在若多个连续返回值类型相同可只保,留最后一个返回值类型名
func add(n1,n2 int) (sum int){
sum = n1 + n2
return
}
sum := add(1,2)
fmt.Println(sum)
示例6:多返回值
在声明函数时使用括号包含所有返回值类型,并使用 return关键字返回,值之间用逗号分割
func calc(n1,n2 int)(int,int,int,int){
return n1 + n2, n1 - n2, n1 * n2, n1 / n2
}
sum, diff, product, quotient := calc(1,2)
fmt.Println(sum, diff, product, quotient)
二、递归
递归是指函数直接或间接调用自己,递归常用于解决分治问题,将大问题分解为相同的小问题进行解决,需要关注终止条件。
示例:阶乘
func fact(n int64) int64 {
if n == 0 || n == 1 {
return 1
}
return n * fact(n-1)
}
func main() {
fmt.Println(fact(5))
}
三、函数类型
函数也可以赋值给变量,存储在数组、切片、映射中,也可作为参数传递给函数或作为函数返回值进行返回
3.1、定义&赋值&调用
定义函数类型的变量
var callback func(int, int) int
赋值为函数
func add(n1,n2 int) int{
return n1 + n2
}
callback = add
调用函数
fmt.Println(callback(1,2))
3.2、参数类型为函数的函数
func tlAdd5(n int) int {
return n + 5
}
func makeMap(list []int, t1 func(int) int) []int {
rt := []int{}
for _,e := range list {
rt = append(rt,t1(e))
}
return rt
}
fmt.Println(makeMap([]int{1,2,3},tlAdd5))
四、匿名函数和闭包
4.1、匿名函数
不需要定义名字的函数叫做匿名函数,常用做帮助函数在局部代码块中使用或作为其他函数的参数
示例1:定义后直接赋值给变量,直接调用
add := func(n1,n2 int) int {
return n1 + n2
}(1,2)
fmt.Println(add)
示例2:参数类型为函数的匿名函数
import (
"fmt"
"strconv"
)
func printResult(n1 int) string {
return strconv.Itoa(n1)
}
func main(){
result := printResult(func(n1,n2 int) int {
return n1 + n2
}(1,2))
fmt.Printf("%T,%v\n",result,result)
}
4.2、闭包
闭包是指在函数内定义的匿名函数引用外部函数的变量,只要匿名函数继续使用则外部函数赋值的变量不被自动销毁
func generateId(start, step int) func() int {
return func() int {
id := start
start += step
return id
}
}
g1 := generateId(1,2)
g5 := generateId(5,5)
fmt.Println(g1(),g5())
fmt.Println(g1(),g5())