How to build string from template in Golang like we do it in C# or Python? See this article.

String formatting in Golang

Michael Ushakov
2 min readOct 7, 2020

I am quite new to golang. I started programming in golang a couple of months ago because I had to develop a solution based on existing golang open source project.

Golang differs from other popular languages like C#, Java or Python, in many ways it resembles modern C language.

In my opinion, there is one thing missing from golang sdk, namely the composite string formatting, which is surprising, considering that the rest of the aforementioned languages support this feature in some form. For instance, in Java you can use it by calling String.format and in Python it’s available through “”.format().

Let’s take a closer look at the issue. Here is an example of the composite formatting in Java:

String.format(“Hello, mr. {0}. You are here: {1}. Good luck mr. {0}.”, “Smith”, “Moscow”);

To reproduce the behavior of this function in Golang we would normally do something like that:

fmt.Sprintf(“Hello, mr. %s. You are here: %s. Good luck mr. %s.”, “Smith”, “Moscow”, “Smith”).

It’s not very convenient because we have to pass the “Smith” argument twice. And that’s just one duplicate value, imagine how confusing it would get if we had to deal with a whole bunch of them.

So, after scratching my head for a little while, I decided to invent my own wheel and make a string formatting like those in C# or Python available in golang. I made a little library currently consisting of two formatting functions which you can find here (https://github.com/Wissance/stringFormatter).

My functions allow me to format a string using either indexed {0}, {1}:

str, err = Format(“Hello {0}, we are greeting you here: {1}!”, “manager”, “salesApp”)

or named placeholders:

str, err = FormatComplex(“Hello {user}, what are you doing here {app} ?”, map[string]string{“user”:”vpupkin”, “app”:”mn_console”})

Since I built the library, I have been actively using these functions to format:
database connection strings,
template-based URLs
complex messages to end-user

Here is an example of how to use it in any golang project:

import “github.com/wissance/stringFormatter” func CreateDbConnectionStr() string {
connStrTemplate := “host={0} port={1} user={2} dbname={3} password={4} sslmode={5}”
connStr, err := stringFormatter.format(connStrTemplate, “127.0.0.1”, “5432”, “developer”, “test_db”, “q1w2e3r4”, “disable”)
return connStr
}

Unfortunately, at the moment, my functions can’t completely substitute fmt.Scanf as they only work with strings while fmt.Scans allows arguments of any type. But I am planning to add support for this feature too. Also, I am going to add support for a format item alignment (i.e., for double/float {0: 0.##} if we pass 123.4567 we get 123.45.) and maybe something else.

--

--

Michael Ushakov
Michael Ushakov

Written by Michael Ushakov

I am a scientist (physicist), an engineer (hardware & software) and the CEO of Wissance (wissance.com)