henry
henry

Reputation: 59

"%!s"-like error in fmt.Printf when format string is from arguments (go language)

just see the code:(so simple that I can't believe myself)

package log

import "fmt"

func P(format string,a ...interface{}){
    fmt.Printf(format,a)
}

when called somewhere like this :

log.P("%s,%s,%d","","",0)

I got error:

[  %!s(int=0)],%!s(MISSING),%!d(MISSING)

BUT if I call fmt.Printf directly like this:

fmt.Printf("%s,%s,%d","","",0)

It works perfectly,just perfectly (of course,as basic use of fmt).

So the Question is:

Why log.P not work??

FYI:

I believe it's pretty simple ,but I just can't find an answer by google, never ever someone dropped in the hell ?

Or maybe I just dont know how to ask,so I put pure code above.

Or just I'm a super fool this time?

I signed up stackoverflow today for an answer to this. Let me know what's wrong with me. As soon...

Upvotes: 4

Views: 9198

Answers (2)

kubistika
kubistika

Reputation: 96

It is just a little mistake. You are calling fmt.Printf with a as a single argument, while it is not. You need to pass it as a variadic argument.

package main

import (
    "fmt"
)

func P(format string, a ...interface{}) {
    fmt.Printf(format, a)
}

func P2(format string, a ...interface{}) {
    fmt.Printf(format, a...)
}

func main() {
    P("%s,%s,%d", "", "", 0)
    fmt.Println()
    P2("%s,%s,%d", "hello", "world", 0)
}

You can read about variadic parameters here.

Upvotes: 5

samix73
samix73

Reputation: 3063

You need to pass a to Printf as variadic and to convert an array to variadic, you need to follow this notation:

func P(format string, a ...interface{}){
    fmt.Printf(format, a...)
}

The Go Programming Language Specification

Passing arguments to ... parameters

If f is variadic with final parameter type ...T, then within the function the argument is equivalent to a parameter of type []T. At each call of f, the argument passed to the final parameter is a new slice of type []T whose successive elements are the actual arguments, which all must be assignable to the type T. The length of the slice is therefore the number of arguments bound to the final parameter and may differ for each call site.


Upvotes: 0

Related Questions