这是我参加字节后端训练营的笔记,承接上文,这一篇继续写写Go语言的基础最基础的语法,既作为自己的笔记,又可以作为文档后面需要时进行查询和阅读。
变参函数
可变参数函数,在调用时可以传递任意数量的参数。 例如,fmt.Println 就是一个常见的变参函数。
package main
import "fmt"
func sum(nums ...int) {
fmt.Print(nums, " ")
total := 0
for _, num := range nums {
total += num
}
fmt.Println(total)
}
func main() {
sum(1, 2)
sum(1, 2, 3)
nums := []int{1, 2, 3, 4}
sum(nums...)
}
输出为
[1 2] 3
[1 2 3] 6
[1 2 3 4] 10
可以看到这个例子里,我们首先写了一个可以接受任意数量的int作为参数的函数func sum(nums ...int),而我们使用的变参函数使用了常规的调用方式,传入独立的参数,比如sum(1, 2),如果我们有一个含有多个值的 slice,并且想把它们作为参数使用,就需要像例子一样使用func(slice...)进行调用。
闭包
Go语言支持匿名函数,并能利用它进行构造闭包,匿名函数在我们想定义一个不需要命名的内联函数时是很实用的,还是以例子的形式进行阐述。
package main
import "fmt"
func intSeq() func() int {
i := 0
return func() int {
i++
return i
}
}
func main() {
nextInt := intSeq()
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())
newInts := intSeq()
fmt.Println(newInts())
}
输出为
1
2
3
1
例子里的intSeq函数返回一个在其函数体内定义的匿名函数,并且返回的函数使用闭包的方式隐藏变量 i,返回的函数隐藏变量i以形成闭包。在后面的例子里我们调用intSeq函数,并且将返回值赋给 nextInt。因为这个函数里已经包含了自己的值 i,所以每次调用 nextInt 时,都会更新 i 的值。
递归
不仅是Go语言,几乎所有编程语言都支持递归,这里我们使用示例阐述它的用法。
package main
import "fmt"
func fact(n int) int {
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fmt.Println(fact(7))
var fib func(n int) int
fib = func(n int) int {
if n < 2 {
return n
}
return fib(n-1) + fib(n-2)
}
fmt.Println(fib(7))
}
输出为
5040
13
可以看到例子里,fact函数在到达fact(0)前一直在调用自身。因为闭包也可以是递归的,所以这里我们在定义闭包之前使用了类型化的var显式声明闭包。并且因为fib之前在main中声明过,所以Go 知道在这里用fib调用哪个函数,非常便捷。