Golang:fmt,variadic args和%!(EXTRA type = value)错误

时间:2015-10-28 19:49:25

标签: go

我在标准日志包周围实现了一个包装器,以创建一个具有各种日志级别的记录器。

我有以下界面:

type Logger interface {
  Trace(fmt string, args ...interface{})
  Debug(fmt string, args ...interface{})
  Info(fmt string, args ...interface{})
  Warn(fmt string, args ...interface{})
  Error(fmt string, args ...interface{})
  Fatal(fmt string, args ...interface{})
  Panic(fmt string, args ...interface{})
}

在实现中,我有类似的东西(不是确切的代码)

func Info(format string, args ...interface{}){
  msg := fmt.Sprintf(format, args...)
  log.Println(msg)
}

现在,假设我像这样打电话给我的图书馆:

logger.Info("Hello %s", "World")

我得到了打印输出:" Hello%!(EXTRA string = WORLD)",而不是预期的" Hello World"。如果我这样做有类似的输出

msg := fmt.Sprintf(format, args)

这将返回" Hello World%!EXTRA [] interface {} = []"。

3 个答案:

答案 0 :(得分:8)

我无法重现此行为。你确定这不是一个你忘了在这里展示的简单错误吗?

https://play.golang.org/p/-jtmll17Xj

package main

import "fmt"

func Info(format string, args ...interface{}){
    msg := fmt.Sprintf(format, args...)
    fmt.Print(msg)
}

func main() {
    Info("Hello %s", "World")
}

打印

Hello World

根据the fmt docs,当您传递额外参数时,%!(EXTRA string=WORLD)会被添加到字符串中,这是格式意外的。也许您使用格式字符串"Hello World"而不是"Hello %s",或者传递参数两次?

答案 1 :(得分:3)

错误发生在椅子和键盘之间。我混淆了以下界面:

func Print(v ...interface{})
func Printf(format string, v ...interface{})

我的一些代码是在没有格式字符串的情况下调用库。请参阅此处以获取更详细的示例:http://play.golang.org/p/Xx79qujaFp

答案 2 :(得分:0)

当您的消息没有动词并且varargs为空但来自其他地方时,也会发生

func CustomPrintf(message string, a ...interface{}) {
    fmt.Printf(message, a) // for no verbs in message you'll get this "EXTRA" suffix
}

这是一般错误的特例。您必须先传播a。因此,请使用fmt.Printf(message, a...)将其重新设置为varags。