Golang:fmt,可变参数和%!(EXTRA type=value)错误

16

我正在实现一个对标准日志包进行封装的接口,以便创建具有不同日志级别的记录器。

我拥有以下接口:

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{}=[]"。


你的格式字符串参数被称为 fmt,但在 Sprintf 调用中却使用了 format - JimB
1
这并没有展示你所描述的内容:http://play.golang.org/p/IKwT8oKX3k - JimB
5个回答

20

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

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
根据fmt文档,当您传递格式外的参数时,%!(EXTRA string=WORLD)会添加到字符串中。也许您正在使用格式字符串"Hello World"而不是"Hello %s",或者重复传递了参数?

1
错误确实出现在椅子和键盘之间。我混淆了以下接口:`func Print(v ...interface{})' 和 'func Printf(format string, v ...interface{})`我的一些代码在没有格式字符串的情况下调用库。请参见此处以获取更详细的示例:链接 - dialAlpha
@BoppreH 那个 fmt 文档参考非常有价值。 - Dustin Oprea

10

出错的原因在于使用者和键盘之间。我混淆了以下接口:

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

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


0

同样,由于简单的(打字错误?)如果您忘记/错过输入“%”,也会发生这种情况。

fmt.Printf("v\n", myvar) 

替代

fmt.Printf("%v\n", myvar)

显然不是“语法”错误,所以编译器无法捕获。 我意识到这与其他答案的结果相同,但我认为这更清晰(也许?)是最常见的原因。

0
这可能发生在您将nil参数传递给格式的情况下,例如:
myStr := fmt.Sprintf("check/%s", "hello", nil)

将myStr的值设置为:"check/hello%!"。在这个例子中,额外的参数是具有nil值的第三个参数。

因此,请确保删除任何多余的参数。


0

当你的消息没有动词且可变参数为空,但来自其他地方时也会发生这种情况:

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...) 再次将其转换为可变参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接