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"
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")
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With