'Golang: fmt, variadic args and %!(EXTRA type=value) error
I'm implementing a wrapper around the standard log package to make a logger with various log levels.
I have the following interface:
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{})
}
In the implementation I have something like this (not the exact code)
func Info(format string, args ...interface{}){
msg := fmt.Sprintf(format, args...)
log.Println(msg)
}
Now, assume I call my library like this:
logger.Info("Hello %s", "World")
I get the printout: "Hello %!(EXTRA string=WORLD)", instead of the expected "Hello World". There a similar output if I do
msg := fmt.Sprintf(format, args)
This returns "Hello World%!EXTRA []interface{}=[]".
Solution 1:[1]
The error was between the chair and keyboard. I mixed up the following interfaces:
func Print(v ...interface{})
func Printf(format string, v ...interface{})
Some of my code was calling the library without a format string.See here for a more detailed example: http://play.golang.org/p/Xx79qujaFp
Solution 2:[2]
Happens aswell when your message has no verbs and the varargs are empty but coming from elsewhere:
func CustomPrintf(message string, a ...interface{}) {
fmt.Printf(message, a) // for no verbs in message you'll get this "EXTRA" suffix
}
That's a special case of a general error. You've got to spread a first. So use fmt.Printf(message, a...) to make it to varags again.
Solution 3:[3]
This can happen if you pass nil params to your format, for instance:
myStr := fmt.Sprintf("check/%s", "hello", nil)
will set the value of myStr to: "check/hello%!" In this example the extra params was the third param with nil value.
so make sure to remove any extra params.
Solution 4:[4]
Also, happens due to a simple (typo?) if you forget/miss putting in the "%". e.g.
fmt.Printf("v\n", myvar)
instead of
fmt.Printf("%v\n", myvar)
obviously not a "syntax" error, so nothing for the compiler to catch. I realize this nets out to the same as some of the other answers, but I think this is clearer and (maybe?) the most common cause.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | dialAlpha |
| Solution 2 | NotX |
| Solution 3 | ori888 |
| Solution 4 |
