多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 可变参数类型 可变参数是指函数传入的参数个数是可变的,为了做到这点,首先需要将函数定义为可以接受可变参数的类型: ~~~ func myfunc(args ...int) { for _, arg := range args { fmt.Println(arg) } } ~~~ ## 任意类型的可变参数 之前的例子中将可变参数类型约束为 int,如果你希望传任意类型,可以指定类型为 interface{},下面是Go语言标准库中 fmt.Printf() 的函数原型: ~~~ func Printf(format string, args ...interface{}) { // ... } ~~~ ## 遍历可变参数列表——获取每一个参数的值 可变参数列表的数量不固定,传入的参数是一个切片,如果需要获得每一个参数的具体值时,可以对可变参数变量进行遍历,参见下面代码: ~~~ package main import ( "bytes" "fmt" ) // 定义一个函数, 参数数量为0~n, 类型约束为字符串 func joinStrings(slist ...string) string { // 定义一个字节缓冲, 快速地连接字符串 var b bytes.Buffer // 遍历可变参数列表slist, 类型为[]string for _, s := range slist { // 将遍历出的字符串连续写入字节数组 b.WriteString(s) } // 将连接好的字节数组转换为字符串并输出 return b.String() } func main() { // 输入3个字符串, 将它们连成一个字符串 fmt.Println(joinStrings("pig ", "and", " rat")) fmt.Println(joinStrings("hammer", " mom", " and", " hawk")) } ~~~ ## 获得可变参数类型——获得每一个参数的类型 当可变参数为 interface{} 类型时,可以传入任何类型的值,此时,如果需要获得变量的类型,可以通过 switch 获得变量的类型,下面的代码演示将一系列不同类型的值传入 printTypeValue() 函数,该函数将分别为不同的参数打印它们的值和类型的详细描述。 打印类型及值: ~~~ package main import ( "bytes" "fmt" ) func printTypeValue(slist ...interface{}) string { // 字节缓冲作为快速字符串连接 var b bytes.Buffer // 遍历参数 for _, s := range slist { // 将interface{}类型格式化为字符串 str := fmt.Sprintf("%v", s) // 类型的字符串描述 var typeString string // 对s进行类型断言 switch s.(type) { case bool: // 当s为布尔类型时 typeString = "bool" case string: // 当s为字符串类型时 typeString = "string" case int: // 当s为整型类型时 typeString = "int" } // 写字符串前缀 b.WriteString("value: ") // 写入值 b.WriteString(str) // 写类型前缀 b.WriteString(" type: ") // 写类型字符串 b.WriteString(typeString) // 写入换行符 b.WriteString("\n") } return b.String() } func main() { // 将不同类型的变量通过printTypeValue()打印出来 fmt.Println(printTypeValue(100, "str", true)) } ~~~ ## 在多个可变参数函数中传递参数 可变参数变量是一个包含所有参数的切片,如果要将这个含有可变参数的变量传递给下一个可变参数函数,可以在传递时给可变参数变量后面添加`...`,这样就可以将切片中的元素进行传递,而不是传递可变参数变量本身。 下面的例子模拟 print() 函数及实际调用的 rawPrint() 函数,两个函数都拥有可变参数,需要将参数从 print 传递到 rawPrint 中。 可变参数传递: ~~~ package main import "fmt" // 实际打印的函数 func rawPrint(rawList ...interface{}) { // 遍历可变参数切片 for _, a := range rawList { // 打印参数 fmt.Println(a) } } // 打印函数封装 func print(slist ...interface{}) { // 将slist可变参数切片完整传递给下一个函数 rawPrint(slist...) } func main() { print(1, 2, 3) } ~~~