4.1.4 多返回值及变长参数
Go语言函数的简单特性主要体现在函数可以返回多个返回值、变长参数等方面,对此也有必要通过示例说明一下:
book/ch04/4.1/argu/main.go
1. package main
2.
3. import "fmt"
4.
5. func main() {
6. fmt.Println(swap(1,2))
7. fmt.Println(sum(1,2,3,4,5,6,7,8,9,10))
8. argus := []int{2,3,4,5,6,7,8,9,10}
9. fmt.Println(sum(1,argus...))
10. args := []interface{}{1234,"abcd"}
11. print(args)
12. print(args...)
13. }
14.
15. func swap(a,b int) (int,int) {
16. return b,a
17. }
18.
19. func sum(a int,others ...int) int {
20. for _,v := range others{
21. a += v
22. }
23. return a
24. }
25.
26. func print(a ...interface{}) {
27. fmt.Println(a...)
28. }
29.
30. //以下是程序运行结果
31. 2 1
32. 55
33. 55
34. [1234 abcd]
35. 1234 abcd
第7行至第9行演示的是对sum函数的两种调用方式。第一种是直接传入要求和的所有数字,并用逗号隔开。第二种是定义一个int类型的切片,把这个切片传进去,注意传参数的时候要带省略号“...”(第9行)。
第15行至第17行是一个交互赋值的例子。通过这个例子可以看到多个参数和多个返回值的写法。这个例子很简单,就不做过多解释了。
第19行至第24行是可变长函数的定义。注意在定义参数的时候前面加上省略号就可标明定义的是可变长参数。这里先定义一个int类型的参数a,后面是任意个int数值(可变长参数),函数会求和然后返回。
第26行至第28行,注意空接口也可以定义可变长参数,这就意味着可以传任何类型的参数,而且在同一个切片里可以有不同类型的元素,比如本例就是把数字和字符串定义在一个空接口切片中的。
第10行至第12行,是对于变长interface{}类型的使用。请注意参数后加省略号和不加省略号导致的执行结果的区别(对应的结果行是第34行和第35行)。加省略号的作用是把切片里面的值解析出来再传递。
这里要强调一下函数的参数传递方式。Go语言中,函数的参数只能进行值传递,不能进行引用传递。虽然可以使用指针,但是本质上传递的还是指针指向的地址,因为访问的是地址内的值,所以会被误认为是引用传递。比如,切片会让人觉得函数在处理切片时使用的是引用传递,其实是因为切片里面包含地址,所以可以直接访问。此外,切片包含的长度和容量也是通过值传递传到函数内的,如果在函数内修改了长度或容量,函数外的切片是接收不到的,所以需要再返回一个切片,也是基于这个原因,append函数才会每次都返回切片。
注意
函数的参数传递只有值传递一种方式,即便是使用指针,也是使用值传递的方式传递了指针的值。请注意上面介绍的切片作为参数时的用法。