Go函数
普通函数
-
与Java相比,Go中的函数在声明时可以声明多个返回值(如果有多个,就用括号包裹,并用逗号分隔)
func 函数名(参数)(返回值){ 函数体 }
- 函数的参数与返回值都是可选的
函数调用
-
Go中的函数调用栈是大小是动态的,因此不用担心函数的递归调用深度,不会产生因大规模递归导致的内存溢出
-
函数调用时的右边的小括号可以换行写,此时为了防止编译器在行尾自动插入分号而导致的编译错误,可以在末尾的参数变量后面插入逗号
for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex( size+int(x*size+0.5), size+int(y*size+0.5), blackIndex, // 最后插入的逗号不会导致编译错误,这是Go编译器的一个特性 ) // 小括弧另起一行缩进,和大括弧的风格保存一致 }
参数
类型省略
-
函数的参数中如果相邻变量的类型相同,则可以省略前边的参数的类型
// a b c三个参数的类型都是int func functionDemo(a, b , c int, d string) { }
可变参数
-
与Java的类似,也是使用
...
(Java是类型 ...
,Go是...类型
)表示函数的可变参数,可变参数都要放在参数表中的最后一个(由解析逻辑决定,放在前边会出现解析的歧义)func main() { functionDemo(1,2,3,4,5,6) } func functionDemo(a, b int, c ...int) { for _,v := range c{ fmt.Println(v) } }
- 可变参数按照切片处理,Java中是按照数组来处理
-
如果可变参数函数的传入参数是切片类型,可以在调用函数时使用
...
展开切片// Sum 测试可变参数函数,参数求和 func Sum(c ...int) int { var result int for _, v := range c { result += v } return result } func main() { println(function.Sum(1, 2, 3)) s := []int{ 2, 3, 4} // 切片展开 println(function.Sum(s...)) }
- 不要混淆:可变参数函数内部将可变参数按照切片处理,不代表切片类型与可变参数兼容,因此上述代码中的
Sum
函数不会接收一个切片类型的参数,只接受其展开
- 不要混淆:可变参数函数内部将可变参数按照切片处理,不代表切片类型与可变参数兼容,因此上述代码中的
-
可变参数函数的最常用的场景就是格式化输出,比如
func Printf(format string, a ...interface{}) (n int, err error)
或func Sprintf(format string, a ...interface{}) string
,函数名的后缀f是一种通用的命名规范,代表该可变参数函数可以接收Printf风格的格式化字符串
注意事项
-
参数名可以设置为
_
表示该参数在函数体内并未使用,仅起占位符的作用 -
参数名可以全部设置为空,表示函数内部不使用参数
func Test(int, int) int64 { return 12 }
返回值
多返回值
func functionDemo(a, b int, c ...int) (int, int) {
return 1, 2
}
func main() {
a,b := functionDemo(1, 2, 3, 4, 5, 6)
fmt.Println(a,b)
}
- 多返回值的特性常常用在错误处理中,即指定一个返回值为Error类型,以便于在函数内部出错时将详细错误返回给函数调用者,参考函数错误处理章节
bare return
func functionDemo1(a, b int, c ...int) (res, res1 int) {
res = 1
res1 = 2
return
}
func main() {
c,d := functionDemo1(1, 2, 3, 4, 5, 6)
fmt.Println(c,d)
}
-
在函数声明的返回值处直接声明返回值变量(同样满足函数参数中的简写原则),在函数体中可以直接使用,并且在返回值变量得到赋值后,直接一个
return
语句即可将返回值返回 -
注意在
bare return
模式下,即便是仅有一个返回值,在函数声明时也要用括号包裹 -
bare return
模式下,如果函数体内部有明确的无法返回的逻辑,则return可以不写,比如遇到死循环,或者是panic -
当函数中有很多return时,使用bare return可以减少代码量,但是降低代码的可读性
函数错误处理
-
关于Go中的函数错误处理与Go异常的区别,参考Go异常处理
-
对于可能出现运行失败的函数,除了本来的函数处理结果对应的返回值之外,一般会返回一个额外的返回值,通常是最后一个返回值,用来表示函数处理是否失败:
-
如果导致失败的原因只有一个则返回一个bool类型值,一般被命名为ok
-
如果导致失败的原因不止一个,比如IO
-