可变参数函数

1|0一、可变参数函数

1|11. 概念

  • 可变参数相当于python中定义的函数它的参数中args的功能,用来接收多个参数,而参数中带有可变参数的函数就叫可变参数函数

1|22. 语法

  • 而Go中可变参数是用 ...T 来表示的,而且只能加在函数参数的最后,表示这个函数可以接收任意个(0到无数个) T 类型的参数作为最后一个参数(即只有函数的最后一个参数才允许时可变的

1|33. 工作原理

  • 可变参数函数的工作原理是把接收的多余参数全部转换为一个新的切片,再将这个切片当作一个参数传给函数

2|0二、创建一个可变参数函数

创建了一个可变参数函数find , package main import ( "fmt" ) func find(num int, nums ...int) { fmt.Printf("type of nums is %T\n", nums) found := false for i, v := range nums { if v == num { fmt.Println(num, "found at index", i, "in", nums) found = true } } if !found { fmt.Println(num, "not found in ", nums) } fmt.Printf("\n") } func main() { find(89, 89, 90, 95) find(45, 56, 67, 45, 90, 109) find(78, 38, 56, 98) find(87) // 不给可变参数nums传参 } /* 这里的 find(89, 89, 90, 95) ,函数中的可变参数 ...int 将 89, 90, 95 编译转换为一个int类型的切片 []int{89, 90, 95} ,然后传给函数find的参数 nums find(45, 56, 67, 45, 90, 109) ,函数中的可变参数 ...int 将 56, 67, 45, 90, 109 编译转换为一个int类型的切片 []int{56, 67, 45, 90, 109} ,然后传给函数find的参数 nums 这里的 find(87) ,函数中的可变参数 ...int 将 空 编译转换为一个int类型的空切片 []int{} ,然后传给函数find的参数 nums,我们仅传给find 函数一个参数。我们没有给可变参数 nums ...int 传入任何参数。这也是合法的,在这种情况下 nums 是一个长度和容量为 0 的 nil 切片 打印结果: type of nums is []int 89 found at index 0 in [89 90 95] type of nums is []int 45 found at index 2 in [56 67 45 90 109] type of nums is []int 78 not found in [38 56 98] type of nums is []int 87 not found in [] */

3|0三、给可变参数函数传入切片

3|11. 错误示范

  • 在二中我们给可变参数传的都属于单个元素,单个元素转换成切片是没有问题的,但是当我们直接给可变参数传入切片会怎么样呢
package main import ( "fmt" ) func find(num int, nums ...int) { fmt.Printf("type of nums is %T\n", nums) found := false for i, v := range nums { if v == num { fmt.Println(num, "found at index", i, "in", nums) found = true } } if !found { fmt.Println(num, "not found in ", nums) } fmt.Printf("\n") } func main() { nums := []int{89, 90, 95} find(89, nums) } /* 结果是程序报错了,无法这样传值,main.go:23: cannot use nums (type []int) as type int in argument to find 其实原因很简单,find函数定义的可变参数为 ...int ,意思可以接收int类型的参数,然后将这些int类型参数转化成切片,而我们此时传入的是切片,在转换切片时格式为[]int{nums},这里之所以会失败是因为 nums 是一个 []int类型 而不是 int类型 */

3|22. 正确写法

  • 按照上面的错误示范,的确是不能传切片的,但是有没有别的方法能实现呢,答案是肯定的
  • 这个方法就是在传切片的时候,在切片后加上 ... 后缀,这样做之后,切片将直接传入函数,相当于给可变参数带句话,让可变参数不再创建新的切片
  • 这里提醒一句,由于切片和其底层数组的关系,当你在函数中修改切片时,请确保你知道你自己在做什么
package main import ( "fmt" ) func find(num int, nums ...int) { fmt.Printf("type of nums is %T\n", nums) found := false for i, v := range nums { if v == num { fmt.Println(num, "found at index", i, "in", nums) found = true } } if !found { fmt.Println(num, "not found in ", nums) } fmt.Printf("\n") } func main() { my_nums := []int{89, 90, 95} find(89, my_nums...) // 在 切片my_nums 后面加上 ... 即可实现给可变参数传切片 }

1|0(1)函数中修改传入的切片

package main import ( "fmt" ) func change(s ...string) { s[0] = "Go" s = append(s, "playground") fmt.Println("s:", s, len(s), cap(s)) } func main() { welcome := []string{"hello", "world"} change(welcome...) fmt.Println("welcome:", welcome, len(welcome), cap(welcome)) } /* 打印结果 s: [Go world playground] 3 4 welcome: [Go world] 2 2 切片s 和 切片 welcome 的底层数组都是同一个为 [2]string{"hello", "world"} , 当s[0]= "Go" 对切片值修改时,此时底层数组也会发生变化,底层数组变为 [2]string{"Go", "world"} , 当 对s 切片进行追加时,由于追加后切片长度大于原底层数组,所以要创建新的底层数组,但是又因为原来的底层数组还有切片 welcome 在引用,所以无法被回收, 此时 s切片的底层数组变为 长度为4(变为原底层数组的2倍)的新底层数组,所以打印的s 信息变为[Go world playground] 3 4 */

__EOF__

本文作者BigSun丶
本文链接https://www.cnblogs.com/Mcoming/p/18029521.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   BigSun丶  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示