go语言之可变参函数的深度理解

可变参函数的深度理解:

函数接收的参数数目都是确定的。而可变参数函数的参数数目是不确定的

如果一个函数的最后一个参数的表示形如:…Type,则该参数(形参)可以接受不同数目的参数(实参)

func f(elems ...Type)

需要注意的一点,只允许最后一个参数是可变参数

Go 中的一些内置函数都是可变参数函数:

例如:append()函数:

func append(slice []Type, elems ...Type) []Type
s := []int{1,2,3}
s = append(s,4,5,6,7,8)

elems就是可变参数,可以接收任意数目的实参

可变参的原理:

func test(str1 string, s ...string) {
 fmt.Println(str1)
 fmt.Printf("%T\n",s)     // %T 输出变量类型
 fmt.Println(s)
}

func main() {
 str:= "net"
 test(str,"Hello","World","Go")
}

//输出:
net
[]string
[Hello World Go]

test()函数中,参数s是[]string类型的切片
可变参数函数的工作原理就是把可变参数转化成切片
调用test()函数时可变参数是Hello、World、Go,这三个参数被编译器转化成切片[]string{“Hello”,“World”,“Go”} ,然后被传入test()函数
另外,调用test()函数时候,可以不传可变参数,在 Go 语言里也是合法的,这种情况下,s是一个长度和容量都是 0 的 nil 切片
将切片传递给可变参数函数

func test(str1 string, s ...string) {
 fmt.Println(str1)
 fmt.Printf("%T\n",s)
 fmt.Println(s)
}

func main() {
 slice := []string{"Hello","World","Go"}
 str := "net"
 test(str,slice)
}

将切片slice传给可变参数函数test(),结果编译出错:
cannot use slice (type []string) as type string in argument to 

由可变参数函数的定义可知,s …string 意味它可以接受 string 类型的可变参数。slice作为可变参数传入test()函数。前面我们知道,可变参数会被转换为 string 类型切片然后再传入test()函数中。但slice是一个 string 类型的切片,编译器试图通过下面这种方式在slice基础上再创建一个切片

test("net", []string{s})
之所以会失败,因为slice是[]string类型,而不是string类型

解决方法:
Go 提供了将切片传入可变参数函数的语法糖:
直接在切片后加上…后缀。这样,切片将直接传入函数,不会再创建新的切片

test(blog,slice...)
//输出:
net
[]string
[Hello World Go]

如果在函数中改变切片的值会发生什么呢?

func test(s ...string) {
 s[0] = "net"
 fmt.Printf("%T\n",s)
 fmt.Println(s)
}

func main() {
 slice := []string{"Hello","World","Go"}
 test(slice...)
 fmt.Println(slice)
}
//输出:
[]string
[net World Go]
[net World Go]

使用了...,切片本身会作为参数直接传入,不会再创建一个新的切片。
所以在test()函数中,第一个元素被替换成 net,会影响到main()函数的切片

可以通过将数组转化成切片传递给可变参数函数:

func test(s ...string) {
 s[0] = "net"
 fmt.Printf("%T\n",s)
 fmt.Println(s)
}

func main() {
 arr := [3]string{"Hello","World","Go"}
 test(arr[:]...)
 fmt.Println(arr)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值