go语言函数变参

作者: CodingCode | 来源:发表于2017-09-22 16:54 被阅读8次

例子

函数变参的定义:
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)

相关文章

  • 函数变参的使用

    介绍C/C++,java,和go语言对函数变参的使用。 1. C/C++语言的变参 1.1 变参函数声明 变参函数...

  • go语言函数变参

    例子 函数变参的定义:func Printf(format string, a ...interface{}) (...

  • Go语言函数

    GO语言函数 GO语言是由函数组成的 没有返回值没有形参的函数 有返回值没有形参的函数 没有返回值有形参的函数 有...

  • 09-Go语言函数

    函数 Go语言函数格式func 函数名称(形参列表)(返回值列表){函数语句} Go语言函数的类型没有返回值没有形...

  • 06-GoLang函数

    函数格式 C语言中 Go语言中 C语言函数的类型 1.没有返回值没有形参的函数 .2.有返回值没有形参的函数 3....

  • go web 编程笔记

    函数 go函数接受变参func x(arg ...init)int {} defer defer 会按照后进先出的...

  • 局部变量和全局变量

    什么是局部变量? 在Go语言和C语言中写在{}中或者函数中或者函数的形参, 就是局部变量 什么是全局变量? 在Go...

  • 2021-06-08

    Go的编程模式,错误处理 引入了其他语言的错误处理模式,最后,说明Go错误处理的好处。主要是将函数的入参、出参、错...

  • Go语言之函数传参

    1.如下代码中的函数传参 filter函数的第二个参数是函数,可以看到直接将isOdd, isEven传入了。

  • 《日子》golang-函数function

    函数function -Go函数不支持嵌套、重载和默认参数-但支持以下特性-无需声明原型、不定长度变参、多返回值、...

网友评论

    本文标题:go语言函数变参

    本文链接:https://www.haomeiwen.com/subject/qbotextx.html