DEV Community

Cover image for String formatting in Golang
Ushakov Michael
Ushakov Michael

Posted on • Edited on

String formatting in Golang

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 a modern version of 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} and have a nice day.", "Smith", "Office");
Enter fullscreen mode Exit fullscreen mode

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. and have a nice day", "Smith", "Office", "Smith").
Enter fullscreen mode Exit fullscreen mode

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.
My functions allow me to format a string using either indexed {0}, {1}:

str = Format("Hello {0}, we are greeting you here: {1}!", "manager", "salesApp")
Enter fullscreen mode Exit fullscreen mode

or named placeholders:

str = FormatComplex("Hello {user}, what are you doing here {app} ?", map[string]string{"user":"vpupkin", "app":"mn_console"})
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)