函数是每一门语言都需要掌握的基本内容,通过函数我们可以将能够复用的代码封装在一个模块中方便我们后续的调用,所以函数其实也有利于模块化的开发,下面是go语言函数中常见的知识点:
① go语言函数定义格式如下,使用func关键字来定义一个函数,函数声明包含一个函数名function_name,参数列表parameter_list, 返回值列表return_types和函数体,如果函数没有返回值,则返回类型return_types可以省略。
func function_name([parameter_list]) [return_types] {
函数体
}
package main
import "fmt"
//当两个或多个连续的函数命名参数是同一类型, 则除了最后一个类型之外, 其他都可以省略
func sum(x, y, z int, s string) int { // fun关键字定义函数的时候左大括号不能另起一行
res := x + y + z
fmt.Println(fmt.Sprintf(s, res))
return x + y + z
}
func main() {
fmt.Println(sum(1, 2, 4, "Hello"))
}
② 函数可以没有参数或接受多个参数;
③ 注意类型在变量名之后,当两个或多个连续的函数命名参数是同一类型,则除了最后一个类型之外,其他都可以省略;
④ 函数支持0个或者多个返回值,多个返回值需要使用小括号括起来;
⑤ 支持匿名函数和闭包,不支持嵌套:一个包不能够有两个名字一样的函数,不支持重载,不支持默认参数;
⑥ 函数中的参数传递有两种:第一种是值传递,第二种是引用传递,值传递指的是在函数调用的时候将实参复制一份传递给函数形参上,引用传递指的是在函数调用的时候将实际参数的地址传递到函数中,在函数中对形参的修改也会影响到实参,一般默认是值传递,map、slice、chan、指针、interface默认以引用的方式传递:
package main
import "fmt"
// 传递切片参数
func func1(a []int, b []int) int {
s := 0
// 遍历切片b求解所有元素之和
for _, v := range b {
s += v
}
a[0] = 100
return s
}
// 省略返回值类型, 如果使用return会直接报: too many arguments to return
func func2(a, b int, args ...int) {
s := 0
for _, v := range args {
s += v
}
fmt.Println(s)
}
func main() {
data := []int{1, 2, 4, 6, 8, 10}
a, b := data[:3], data[3:]
fmt.Println(func1(a, b))
fmt.Println(a, b)
// 传递的是切片所以也会修改原数组的值
fmt.Println(data)
fmt.Println("append方法: ")
data2 := []int{2, 4, 6, 8, 10}
data3 := []int{}
// 注意需要在data2后面加上...
data3 = append(data3, data2...)
fmt.Println(data2, data3)
func1(data2, data3)
// 修改切片data3的值不会修改data2的值
fmt.Println(data2, data3)
// 使用copy方法
fmt.Println("copy方法: ")
data4, data5 := []int{1, 2, 3, 4, 5}, make([]int, 5)
copy(data5, data4)
data5[0] = -9
data4[1] = -1
fmt.Println(data4, data5)
// 传递多个参数
fmt.Println("传递多个参数可以使用args..., 并且需要写在最后面: ")
func2(23, 17, 2, 4, 6)
}
⑦ 递归函数,go语言的递归函数与其他语言还是比较像的,需要在递归函数中设置一个出口,下面是求解n!的例子:
package main
import "fmt"
// 计算n的阶乘
func fac(n int) int {
if n <= 1 {
return 1
}
return n * fac(n - 1)
}
func main() {
var a int
// 从控制台输入整数存储到变量a中
fmt.Scan(&a)
fmt.Println(fac(a))
}
⑧ 匿名函数
如果我们暂时不想给函数取一个名字,那么可以使用匿名函数的方式,也即省略函数的名字,可以将匿名函数赋值给变量,使用变量进行调用,或者是直接在匿名函数后面添加上小括号直接调用:
package main
import (
"fmt"
)
func main() {
// 1. 匿名函数赋值给变量, 使用变量调用匿名函数
g := func(x, y int) int {
return x + y
}
// 利用变量调用匿名函数
fmt.Println(g(2, 6))
// 2. 右括号最后一对小括号就是对匿名函数的调用
func(s string) {
fmt.Println(s)
}("hellow world!")
}