Go开发之路 -- 函数详解
声明语法
func 函数名 (参数列表) [(返回值列表)] {}
Golang函数特点
a. 不支持重载,一个包不能有两个名字一样的函数
b. 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
c. 匿名函数
d. 多返回值
函数的参数传递方式
值传递
引用传递
注意1:
无论是值传递,还是引用传递,传递给函数的都是变量的副本,
不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址
拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能
越低。
注意2:
map、slice、chan、指针、interface默认以引用的方式传递
/* package main import "fmt" func modify(a int) { a = 100 } func main(){ a := 8 fmt.Println(a) modify(a) fmt.Println(a) } */ // 修改上面的程序, 使其正确 package main import "fmt" func modify(a *int) { *a = 100 } func main(){ a := 8 fmt.Println(a) modify(&a) fmt.Println(a) }
命名返回值的名字
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 main() { sum, _ := calc(100, 200) }
可变参数
func add(arg…int) int { // 0个或多个参数 }
func add(i int, arg…int) int { // 1个或多个参数 }
func add(i int, j int, arg…int) int { // 2个或多个参数 }
注意:
其中arg是一个slice,我们可以通过arg[index]依次访问所有参数
通过len(arg)来判断传递参数的个数
// 写一个函数add, 支持一个或多个int相加, 并返回相加结果 package main import "fmt" func add(x int, arg...int) int{ var sum int = x for i := 0; i < len(arg); i++ { sum += arg[i] } return sum } func main(){ res := add(2, 2) fmt.Println(res) }
// 写一个函数concat, 支持一个或者多个string相拼接, 并返回结果 package main import "fmt" func concat(str string, arg...string)(res string){ res = str for i := 0; i < len(arg); i++ { res += arg[i] } return } func main(){ res := concat("plm", "asd") fmt.Println(res) }
defer的用途
1. 当函数返回时,执行defer语句。因此,可以用来做资源清理 2. 多个defer语句,按 先进后出 的方式执行 3. defer语句中的变量,在defer声明时就决定了
应用:
1. 关闭文件句柄
func read(){ file := open(filename) defer file.Close() //文件操作 }
2. 锁资源释放
func read() { mc.Lock() defer mc.Unlock() //其他操作 }
3. 数据库连接释放
func read() { conn := openDatabase() defer conn.Close() //其他操作 }