26

Is it possible using fmt.Sprintf() to replace all variables in the formatted string with the same value?

Something like:

val := "foo"
s := fmt.Sprintf("%v in %v is %v", val)

which would return

"foo in foo is foo"

2 Answers 2

48

It's possible, but the format string must be modified, you must use explicit argument indicies:

Explicit argument indexes:

In Printf, Sprintf, and Fprintf, the default behavior is for each formatting verb to format successive arguments passed in the call. However, the notation [n] immediately before the verb indicates that the nth one-indexed argument is to be formatted instead. The same notation before a '*' for a width or precision selects the argument index holding the value. After processing a bracketed expression [n], subsequent verbs will use arguments n+1, n+2, etc. unless otherwise directed.

Your example:

val := "foo"
s := fmt.Sprintf("%[1]v in %[1]v is %[1]v", val)
fmt.Println(s)

Output (try it on the Go Playground):

foo in foo is foo

Of course the above example can simply be written in one line:

fmt.Printf("%[1]v in %[1]v is %[1]v", "foo")

Also as a minor simplification, the first explicit argument index may be omitted as it defaults to 1:

fmt.Printf("%v in %[1]v is %[1]v", "foo")
Sign up to request clarification or add additional context in comments.

Comments

3

You could also use text/template:

package main

import (
   "strings"
   "text/template"
)

func format(s string, v interface{}) string {
   t, b := new(template.Template), new(strings.Builder)
   template.Must(t.Parse(s)).Execute(b, v)
   return b.String()
}

func main() {
   val := "foo"
   s := format("{{.}} in {{.}} is {{.}}", val)
   println(s)
}

https://pkg.go.dev/text/template

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.