函数
假设 f1 需要 3 个参数 f1(a, b, c int)
,同时 f2 返回 3 个参数f2(a, b int) (int, int, int)
,就可以这样调用 f1: f1(f2(a, b))
Go 语言不支持函数重载 函数重载(function overloading)指的是可以编写多个同名函数,只要它们拥有不同的形参与/或者不同的返回值,在 Go 里面函数重载是不被允许的。 这将导致一个编译错误:
函数也可以以申明的方式被使用,作为一个函数类型,就像:
type binOp func(int, int) int
6.2.4 改变外部变量
指针传递
6.3 传递变长参数
6.4 defer
关键字 defer
允许我们推迟到函数返回之前(或任意位置执行 return
语句之后)一刻才执行某个语句或函数,因为 return
语句同样可以包含一些操作,而不是单纯地返回某个值
注:可以用来记录程序开始和结束时间
func Function1() {
fmt.Printf("In Function1 at the top\n")
defer Function2() // 加不加这个关键字是有很大区别的
//Function2()
i := 0
defer fmt.Println(i)
i++
fmt.Printf("In Function1 at the bottom!\n")
return
}
func Function2() {
fmt.Printf("函数2:延迟到调用函数结束!\n")
}
当有多个 defer 行为被注册时,它们会以逆序执行(类似栈,即后进先出):下面代码会输出 4 3 2 1 0
func f() {
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
}
6.6 递归函数
在使用递归函数时经常会遇到的一个重要问题就是栈溢出
:一般出现在大量的递归调用导致的程序栈内存分配耗尽。 这个问题可以通过一个名为懒惰求值
的技术解决,在 Go 语言中,我们可以使用管道(channel)和 goroutine(详见第 14.8 节)来实现
可以相互调用,行程闭环
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
fmt.Printf("%d is even: is %t\n", i, even(i))
fmt.Printf("%d is odd: is %t\n", i, odd(i))
}
}
func even(nr int) bool {
if nr == 0 {
return true
}
return odd(RevSign(nr) - 1)
}
func odd(nr int) bool {
if nr == 0 {
return false
}
return even(RevSign(nr) - 1)
}
func RevSign(nr int) int {
if nr < 0 {
return -nr
}
return nr
}