Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace all variables in Sprintf with same variable

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"
like image 295
raphink Avatar asked May 03 '16 10:05

raphink


2 Answers

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")
like image 177
icza Avatar answered Nov 03 '22 21:11

icza


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

like image 2
Zombo Avatar answered Nov 03 '22 22:11

Zombo