加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

了解golang的不定参数(... parameters),这一篇就够了

发布时间:2020-12-16 09:32:53 所属栏目:大数据 来源:网络整理
导读:在实际开发中,总有一些函数的参数个数是在编码过程中无法确定的,比如我们最常用的fmt.Printf和fmt.Println: fmt.Printf( " 一共有%v行%v列n " ,rows,cols)fmt.Println( " 共计大小: " ,size) 当你需要实现类似的接口时,就需要我们的 不定参数 出场了。

在实际开发中,总有一些函数的参数个数是在编码过程中无法确定的,比如我们最常用的fmt.Printf和fmt.Println:

fmt.Printf("一共有%v行%v列n",rows,cols)
fmt.Println("共计大小:",size)

当你需要实现类似的接口时,就需要我们的不定参数出场了。

?

golang的不定参数

顾名思义,不定参数就是一个占位符,你可以将1个或者多个参数赋值给这个占位符,这样不管实际参数的数量是多少,都能交给不定参数来处理,我们看一下不定参数的声明:

func Printf(format string,a ...interface{}) (n int,err error)
func Println(a ...interface{}) (n int,err error)

不定参数使用name ...Type的形式声明在函数的参数列表中,而且需要是参数列表的最后一个参数,这点与其他语言类似;

不定参数在函数中将转换为对应的[]Type类型,所以我们可以像使用slice时一样来获取传给函数的参数们;

有一点值得注意,golang的不定参数不需要强制绑定参数的出现。

举个例子,我想在c语言中实现一个求和任意个整数的函数sum:

int sum(int num,...) {
    // todo
}

我们只有先指定至少一个非不定参数的形参(num)才能使用...不定参数,在golang中是不需要这样做的:

func sum(nums ...int) int {
    //todo
}

这也是golang语法简洁的其中一个体现。

?

传递参数给...不定参数

传递参数给带有不定参数的函数有两种形式,第一种与通常的参数传递没有什么区别,拿上一节的sum举个例子:

sum(1,2,3)
sum(1,3,4,5,6,7,8,9,10)

除了参数的个数是动态变化的之外和普通的函数调用是一致的。

第二种形式是使用...运算符变量...的形式进行参数传递,这里的变量必须是与不定参数类型相同的slice,而不能是其他类型(没错,数组也不可以),看个例子:

numbers := []int{1,10}
sum(numbers...) // 和sum(1,2,3,4,5,6,7,8,9. 10)等价

这种形式最常用的地方是在内置函数append里:

result := []int{1,3}
data := []int{5,9}
result = append(result,data...) // result == []int{1,9}

是不是和python的解包操作很像,没错,大部分情况下你可以把...运算符当做是golang的unpack操作,不过有几点不同还是要注意的:

第一,只能对slice类型使用...运算符:

arr := [...]int{1,5}
sum(arr...) // 编译无法通过

你会见到这样的报错信息:cannot use arr (type [5]int) as type []int in argument to sum

这是因为不定参数实际是个slice,...运算符是个语法糖,它把前面的slice直接复制给不定参数,而不是先解包成独立的n个参数再传递,这也是为什么我只说...运算符看起来像unpack的原因。

第二个需要注意的地方是不能把独立传参和...运算符混用,再看个例子:

slice := []int{2,5}
sum(1,slice...) // 无法通过编译

?这次你会见到一个比较长的报错:

too many arguments in call to sum
    have (number,[]int...)
    want (...int)

这是和前面所说的原因是一样的,...运算符将不定参数直接替换成了slice,这样就导致前一个独立给出的参数不再算入不定参数的范围内,使得函数的参数列表从(...int)变成了(int,...int),最终使得函数类型不匹配编译失败。

正确的做法也很简单,不要混合使用...运算符给不定参数传参即可。

?

读了这篇文章,再加上一些简单的联系,我相信你们一定也能掌握golang不定参数的使用。

参考:

https://golang.org/ref/spec#Passing_arguments_to_..._parameters

https://golang.org/doc/effective_go.html#append

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读