go语言函数变参

例子

函数变参的定义:
func Printf(format string, a ...interface{}) (n int, err error) { ... }

调用方式
Printf("%s-%d-%s", "AAA", 123, "BBB")

传递方式

在函数调用的时候,caller会把所有的变参转换成一个slice对象,然后传递给callee,

package main

import "fmt"
import "reflect"

func foo1(args ...string) {
    fmt.Println("=====foo1()====")
    fmt.Println("Type=", reflect.TypeOf(args))
    fmt.Println("Value=", reflect.ValueOf(args))
    fmt.Println(args)
}

func main() {
    foo1("aaa", "bbb", "ccc")
}

运行结果为:

$ go build && ./main     
=====foo1()====
Type= []string
Value= [aaa bbb ccc]
[aaa bbb ccc]

可以很清楚的看到在foo1函数内,args的类型是[]string是一个slice.

main函数内容可以这么写,能产生同样的结果:

func main() {
    //foo1("aaa", "bbb", "ccc")
    params := []string{"aaa", "bbb", "ccc"}
    foo1(params...) // notice: not foo1(params)
}

如何变参传递给其他变参函数

这里我们讨论的是如何传递变参给另一个变参函数,如果对象不是一个变参函数,那么调用者可以分析slice得到每一个元素,这样就随便处理了。

把变参作为整体传给另一个变参函数也很容易,使用"args..."就行,例如上述代码再调用fmt.Printf

package main

import "fmt"
import _ "reflect"

func foo1(args ...interface{}) {
    fmt.Printf("%s-%s-%s", args...)
}

func main() {
    foo1("aaa", "bbb", "ccc")
}

运行结果

$ go build && ./main 
aaa-bbb-ccc

如果没有使用args...,而是直接使用了args会出什么结果呢?

package main

import "fmt"
import _ "reflect"

func foo1(args ...interface{}) {
    fmt.Printf("%s-%s-%s", args)
}

func main() {
    foo1("aaa", "bbb", "ccc")
}

运行结果:

$ go build && ./main 
[aaa bbb ccc]-%!s(MISSING)-%!s(MISSING)

这里因为"%s-%s-%s",需要三个string类型来匹配,而args作为整体只能算是提供了第一个参数。所以导致
第一个%s <- args, 即[]string {"aaa", "bbb", "ccc"}
第二个%s <- 没有值
第三个%s <- 没有值

常用场景

这个需求经常被用在自定义log输出的场合。比如

func myInfo(formating string, args ...interface{}) {
  // fmt.Printf(fInfoormating+"\n", args...)
  fmt.Printf("INFO: %s", fmt.Sprintf(formatting, args...))
}

func myDebug(formating string, args ...interface{}) {
  // fmt.Printf(fInfoormating+"\n", args...)
  fmt.Printf("DEBUG: %s", fmt.Sprintf(formatting, args...))
}

调用者

myInfo("Hello World");
myDebug("This is the %d bug", 12)
myDebug("This %s are %d", "AAA", 20)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 35,212评论 18 399
  • 第一章五个程序 都很好!但是初学编程/没有其他语言基础的不容易看懂。 记一遍不熟悉的东西: who = strin...
    暗黑破坏球嘿哈阅读 1,593评论 0 10
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,756评论 0 4
  • Java经典问题算法大全 /*【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子...
    赵宇_阿特奇阅读 2,129评论 0 2
  • 一、zabbix简介 zabbix(音同 zæbix)是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企...
    JokerW阅读 4,447评论 2 29

友情链接更多精彩内容