4.4.5 变长参数
变长参数通报的函数在很多措辞里都是支持的,javascript里就有这样的函数, java在1.5往后也开始支持, 同样在go措辞里也支持这样非常方便地变长参数的函数。 比如,我们最常用到的fmt.Println(), 见print.go源文件
// Println formats using the default formats for its operands and writes to standard output.// Spaces are always added between operands and a newline is appended.// It returns the number of bytes written and any write error encountered.func Println(a ...any) (n int, err error) { return Fprintln(os.Stdout, a...)}

如上段源代码,Println函数便是变长参数的函数, ...any,表示数据类型为any的变参数;
下面我们示例一段变长参数的函数的例子
func Average(n ...int) float64 { if len(n) == 0 { return 0 } sum := 0.0 for _, v := range n { sum += float64(v) } return sum / float64(len(n)1.0)}
fmt.Printf("Average()=%v \n", Average())fmt.Printf("Average(1)=%v \n", Average(1))fmt.Printf("Average(1, 6)=%v \n", Average(1, 6))fmt.Printf("Average(1, 2, 3, 4, 5)=%v \n", Average(1, 2, 3, 4, 5))n := append(make([]int, 0), 2, 4, 6, 8, 10, 12)fmt.Printf("Average(%v)=%v \n", n, Average(n...))==== OUTPUT ====Average()=0 Average(1)=1 Average(1, 6)=3.5 Average(1, 2, 3, 4, 5)=3 Average([2 4 6 8 10 12])=7
变长函数的末了一个参数是采取 ...type 的形式,那么这个函数就可以处理一个变长的参数,这个长度可以为 0,这样的函数称为变参函数。如上个例子,我们就定义了一个Average的变长参数的函数,Average函数参数定义为...int,表示处理一个int类型的变长参数,函数的实现,是变量所有的参数,然后累加打算均匀值。 再来看看函数的调用。
Average(), 参数为0个参数
Average(1), 参数为1个参数
Average(1,6), 参数为2个参数
Average(1, 2, 3, 4, 5), 参数为5个参数
Average(n...), 参数为6个参数
把稳末了一个调用参数的办法, Average(n...) n是一个数组或者是切片,可以通过...的办法,把一个数组或者切片转换为变长的参数进行通报, 这个办法在很多源代码里都有类似的调用。
在利用变长函数定义时要把稳
一个变长参数的函数定义里,只能有一个变长的参数定义一个变长的参数的函数定义里,只能是末了一个参数定义能定义为变长的参数
func Says(name string, greets ...string) { word := strings.Join(greets, " ") fmt.Printf("%s: %s\n", name, word)}
func TestReturnFunc2(t testing.T) { Says("Ginghan", "Welcome to", "Golang", "Java", "Python") words := append(make([]string, 0), "like", "Golang", "Java", "Python", "C#", "Php", "C++", "Js") Says("程序员紫龙", words...)}==== OUTPUT ====Ginghan: Welcome to Golang Java Python程序员紫龙: like Golang Java Python C# Php C++ Js
在上面的例子里,定义了Says变长参数的函数; 只能末了一个参数可以定义为变长的参数,如greets ...string;
words := append(make([]string, 0), "like", "Golang", "Java", "Python", "C#", "Php", "C++", "Js")
这里的代码,也是一个变长参数的函数的利用例子, golang里内置的append函数也是一个变长参数的函数, 参考builtin.go代码
// The append built-in function appends elements to the end of a slice. If// it has sufficient capacity, the destination is resliced to accommodate the// new elements. If it does not, a new underlying array will be allocated.// Append returns the updated slice. It is therefore necessary to store the// result of append, often in the variable holding the slice itself:// slice = append(slice, elem1, elem2)// slice = append(slice, anotherSlice...)// As a special case, it is legal to append a string to a byte slice, like this:// slice = append([]byte("hello "), "world"...)func append(slice []Type, elems ...Type) []Type
这个append是处理切片非常常见的函数, 大家一定要熟记这个函数的用法。
变长的办法,只能作为变长参数,不能作为返回值。
func Says(name string, greets ...string) ...string { word := strings.Join(greets, " ") fmt.Printf("%s: %s\n", name, word)}==== Complie Error ====.\build_test.go:546:43: can only use ... with final parameter in list
编译失落败!
!
!