如何使用“…interface{}”参数(类似于Printf)包装函数

huangapple go评论76阅读模式
英文:

How to wrap functions with "...interface{}" argument (like Printf)

问题

在我的当前项目中,我正在尝试编写一个日志函数,该函数将有条件地调用fmt.Println。

我的当前Log函数如下所示:

func Log(level int, a ...interface{}) {
    if level <= LogLevel {
        fmt.Println(a)
    }
}

但是,当我像这样调用它时,Log的输出会因某种原因而被括号包围:

http://play.golang.org/p/Aa8vC54Ih0

package main

import "fmt"

var LogLevel int

func main() {
    fmt.Println("string", 10, 3.1415926)
    LogLevel = 1
    Log(1, "string", 10, 3.1415926)
}

func Log(level int, a ...interface{}) {
    if level <= LogLevel {
        fmt.Println(a)
    }
}

string 10 3.1415926
[string 10 3.1415926]

对我来说,这看起来像是Log中的a参数被某种方式转换了。我该如何将a传递给fmt.Println,以使其与直接调用fmt.Println相同?

英文:

In my current project I am trying to write a logging function that will conditionally call fmt.Println.

My current Log function looks like this:

func Log(level int, a ...interface{}) {
	if level &lt;= LogLevel {
		fmt.Println(a)
	}
}

But when I call it like this the output of Log gets encased in brackets for some reason:

http://play.golang.org/p/Aa8vC54Ih0

package main

import &quot;fmt&quot;

var LogLevel int

func main() {
	fmt.Println(&quot;string&quot;, 10, 3.1415926)
	LogLevel = 1
	Log(1, &quot;string&quot;, 10, 3.1415926)
}

func Log(level int, a ...interface{}) {
	if level &lt;= LogLevel {
		fmt.Println(a)
	}
}

string 10 3.1415926
[string 10 3.1415926]

This to me looks like the a argument in Log gets transformed somehow. How would I go about to pass a to fmt.Println in a way that is identical to calling fmt.Println directly?

答案1

得分: 17

只需将fmt.Println(a)更改为fmt.Println(a...)

请参阅Go规范中的“将参数传递给...参数”http://golang.org/ref/spec#Passing_arguments_to_..._parameters

英文:

Just change fmt.Println(a) to fmt.Println(a...)

See "Passing arguments to ... parameters" in the go spec http://golang.org/ref/spec#Passing_arguments_to_..._parameters

答案2

得分: 0

原始问题不是如何包装一个函数,使其看起来像Printf,而是如何调用这样的函数。但是,按照原始问题的字面意思,我来这里寻找创建和维护包装器的提示。

如果你想知道如何处理go lint提供的一些功能,你可以声明自己编写的使用printf样式格式化的函数,以便检查你的格式语句和参数是否匹配。

例如,

func Infof(fmt string, args ...interface{}) {
    log.Printf("INFO"+fmt+"\n", args...)
}
func Warnf(fmt string, args ...interface{}) {
    log.Printf("WARN"+fmt+"\n", args...)
}

// 这里有一个错误,因为%d没有参数
Infof("Hello %s, can I help you with %d?", "Mark")

像这样运行go vet;

go vet -printfuncs=InfoF,Warnf ./pkg/...

它会告诉你%d缺少一个参数。

英文:

The original question was not how to wrap a function so that it looks like Printf, but how to call such a function. But taking the original question subject verbatim, I came here looking for hints on creating and maintaining the wrappers.

In case you are wondering how to cope with some of the features that go lint provides, you can declare your homegrown functions that use printf style formatters, so that it checks that your format statement and arguments match.

For example,

func Infof(fmt string, args ...interface{}) {
    log.Printf(&quot;INFO&quot;+fmt+&quot;\n&quot;, args...)
}
func Warnf(fmt string, args ...interface{}) {
    log.Printf(&quot;WARN&quot;+fmt+&quot;\n&quot;, args...)
}

// this has a mistake, because there is no argument for %d    
Infof(&quot;Hello %s, can I help you with %d?&quot;, &quot;Mark&quot;)

Run go vet like this;

go vet -printfuncs=InfoF,Warnf ./pkg/...

And it will tell you that your %d is missing an argument.

huangapple
  • 本文由 发表于 2013年7月25日 21:54:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/17860056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定