声明语法
func 函数名 (参数列表) [(返回值列表)] { }
func add() {
} func add(a int, b int) {
} func add(a int, b int) int {
} func add(a int, b int) (int, int) {
} func add(a, b int) (int, int) {
}
golang函数特点
a. 不支持重载,一个包不能有两个名字一样的函数
b. 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
c. 匿名函数
d. 多返回值
package main import "fmt" func add(a, b int) int { return a + b } func main() { c := add fmt.Println(c) sum := c(10, 20) fmt.Println(sum) }
package main import "fmt" type add_func func(int, int) int func add(a, b int) int { return a + b } func operator(op add_func, a int, b int) int { return op(a, b) } func main() { c := add fmt.Println(c) sum := operator(c, 100, 200) fmt.Println(sum) }
函数参数传递方式
1). 值传递
2). 引用传递
注意1:无论是值传递,还是引用传递,传递给函数的都是变量的副本。不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能越低。
map、slice、chan、指针、interface默认以引用的方式传递
命名返回值的名字
func add(a, b int) (c int) { c = a + b return } func calc(a, b int) (sum int, avg int) { sum = a + b avg = (a +b)/2 return }
_标识符,用来忽略返回值
func calc(a, b int) (sum int, avg int) { sum = a + b avg = (a +b)/2 return} func main() { sum, _ := calc(100, 200) }
可变参数
func add(arg…int) int { 0个或多个参数 } func add(a int, arg…int) int { 1个或多个参数 } func add(a int, b int, arg…int) int { 2个或多个参数 }
注意:其中arg是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断传递参数的个数。
defer用途
1. 当函数返回时,执行defer语句。因此,可以用来做资源清理
2. 多个defer语句,按先进后出的方式执行
3. defer语句中的变量,在defer声明时就决定了。
func a() { i := 0 defer fmt.Println(i) i++ return } func f() { for i := 0; i < 5; i++ { defer fmt.Printf(“%d “, i) } }
关闭文件句柄
func read() { file := open(filename) defer file.Close() //文件操作 }
锁资源释放
func read() { mc.Lock() defer mc.Unlock() //其他操作 }
数据库连接释放
func read() { conn := openDatabase() defer conn.Close() //其他操作 }
内置函数
1. close:主要用来关闭channel
2. len:用来求长度,比如string、array、slice、map、channel
3. new:用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针
4. make:用来分配内存,主要用来分配引用类型,比如chan、map、slice
5. append:用来追加元素到数组、slice中
6. panic和recover:用来做错误处理
new和make的区别
递归函数
一个函数调用自己,就叫做递归函数。
package main import ( "fmt" ) func calc(n int) int { if n == 1 { return 1 } return calc(n-1) * n } func main() { n := calc(5) fmt.Println(n) }
斐波那契数
package main import "fmt" func fab(n int) int { if n <= 1 { return 1 } return fab(n-1) + fab(n-2) } func main() { for i := 0; i < 10; i++ { n := fab(i) fmt.Println(n) } }
闭包
闭包:一个函数和与其相关的引用环境组合而成的实体
package main import “fmt” func main() { var f = Adder() fmt.Print(f(1),” - “) fmt.Print(f(20),” - “) fmt.Print(f(300)) } func Adder() func(int) int { var x int return func(delta int) int { x += delta return x } }
闭包实例
package main import ( "fmt" "strings" ) func makeSuffixFunc(suffix string) func(string) string { return func(name string) string { if !strings.HasSuffix(name, suffix) { return name + suffix } return name } } func main() { func1 := makeSuffixFunc(".bmp") func2 := makeSuffixFunc(".jpg") fmt.Println(func1("test")) fmt.Println(func2("test")) }