点击上方蓝色“ Go语言中文网 ”关注, 每天一起学 Go

欢迎来到 Golang 系列教程第 12 部分。

什么是可变参数函数

可变参数函数是一种参数个数可变的函数。

语法

...TT

请注意只有函数的最后一个参数才允许是可变的。

通过一些例子理解可变参数函数如何工作

你是否曾经想过 append 函数是如何将任意个参数值加入到切片中的。这样 append 函数可以接受不同数量的参数。

func append(slice []Type, elems ...Type) []Type

上面是 append 函数的定义。在定义中 elems 是可变参数。这样 append 函数可以接受可变化的参数。

让我们创建一个我们自己的可变参数函数。我们将写一段简单的程序,在输入的整数列表里查找某个整数是否存在。

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)
}

在线运行代码[1]

func find(num int, nums ...int)numsnums
findintint []int{89, 90, 95}find
fornumsnumnumnum

上面代码的输出值如下,

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  []
nums ...intnumsnil

给可变参数函数传入切片

下面例子中,我们给可变参数函数传入一个切片,看看会发生什么。

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)
}

在线运行代码[2]

在第 23 行中,我们将一个切片传给一个可变参数函数。

main.go:23: cannot use nums (type []int) as type int in argument to find
find
func find(num int, nums ...int)
nums ...intint
numsfindintfindnumsnums
find(89, []int{nums})
nums[]intint

那么有没有办法给可变参数函数传入切片参数呢?答案是肯定的。

...
find(89, nums)find(89, nums...)
type of nums is []int
89 found at index 0 in [89 90 95]

下面是完整的程序供您参考。

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...)
}

在线运行代码[3]

不直观的错误

当你修改可变参数函数中的切片时,请确保你知道你正在做什么。

下面让我们来看一个简单的例子。

package main

import (
 "fmt"
)

func change(s ...string) {
 s[0] = "Go"
}

func main() {
 welcome := []string{"hello", "world"}
 change(welcome...)
 fmt.Println(welcome)
}

在线运行代码[4]

[Go world]
...change
...welcomewelcomechange
changeGo
[Go world]

这里还有一个例子来理解可变参数函数。

package main

import (
 "fmt"
)

func change(s ...string) {
 s[0] = "Go"
 s = append(s, "playground")
 fmt.Println(s)
}

func main() {
 welcome := []string{"hello", "world"}
 change(welcome...)
 fmt.Println(welcome)
}

在线运行代码[5]

我将把它作为一个练习留个你,请你指出上面的程序是如何运行的 :) 。

以上就是关于可变参数函数的介绍。感谢阅读。欢迎您留下有价值的反馈和意见。祝您生活愉快。

上一教程 - Array 和 Slice

下一教程 - Maps[6]

推荐阅读

  • Go 经典入门系列 11:数组和切片

福利 我为大家整理了一份 从入门到进阶的Go学习资料礼包 ,包含学习建议:入门看什么,进阶看什么。 关注公众号 「polarisxu」,回复 ebook 获取;还可以回复「进群」,和数万 Gopher 交流学习。

fde7139d7605644988584a602c70fba3.png