DEV Community

Cover image for Exploring the possibilities of Golang string formatting
Brian Neville-O'Neill
Brian Neville-O'Neill

Posted on • Originally published at blog.logrocket.com on

Exploring the possibilities of Golang string formatting

#go

Written by Michiel Mulders✏️

A string is one of the most-used types in software programs. Strings allow developers to display values to the user, such as showing the most important properties of an object. However, we often need additional functionality for converting strings to the desired format.

Let’s say we want to convert a floating-point number with six decimal places to a human-readable price format with only two figures after the decimal point. String formatting comes in handy here. In this guide, we’ll explore the possibilities of Go string formatting.

String formatting: A wide range of possibilities

Golang has a rich set of string formatting options. The foremost package is the built-in fmt package, which provides a wide variety of string formatting functionalities.

This package offers two interesting methods:

  1. Printf
  2. Sprintf

The first method, Printf, prints a formatted string to os.Stdout. However, you may want to use the formatted string to further modify or pass it to another function. Therefore, it would be useful to store the formatted string in a variable. This is exactly what Sprintf does.

s1 := fmt.Sprintf("a %s", "string")
Enter fullscreen mode Exit fullscreen mode

Here, the formatted value a string is stored in the s1 variable. In the next section, we’ll give an overview of the Golang fmt package.

LogRocket Free Trial Banner

The fmt package

The fmt package enables you to convert strings, numbers, and even objects to a particular string format. All of the formatting options discussed below are made possible by the fmt.Printf and fmt.Sprintf functions.

Furthermore, modifying values happens via so-called verbs. A verb refers to the combination of a percentage sign (%) with a letter or number. Each verb formats a value in a different way. For this to work, the fmt.Printf function knows how to interpret these special verbs.

For example, the %d verb enables you to format a number to its base-10 string representation.

fmt.Printf("Number %d", 9)
// Output: Number 9
Enter fullscreen mode Exit fullscreen mode

There are many more interesting verbs you can use. Let’s explore a few different types, starting with general verbs.

General verbs

The most important verb for printing objects is the %v verb. It’s commonly used to quickly print an object as a string, which is helpful for debugging applications. Every Golang developer should be aware of this verb.

In the below example, a Dimension struct is defined. This accepts two parameters: height and length. Next, the %v verb prints the object’s contents.

type Dimension struct {
        height, length int
}   

dimension := Dimension{180, 80}
fmt.Printf("%v", dimension)
// Output: {180 80}
Enter fullscreen mode Exit fullscreen mode

However, those values are quite meaningless. It can be very confusing if you have a struct that holds more than five. Then you have to look up the order of each value in the struct to know which value corresponds to which field. Therefore, a little trick exists to also print the variable names. Use the %+v verb for printing your object next time as it also prints the associated fields.

fmt.Printf("%v", dimension)
// Output: {height:180 length:80}
Enter fullscreen mode Exit fullscreen mode

For some, it might be useful to print the type of the parameter you’re passing in. The %T verb helps with this task. The below example prints the type for an integer.

fmt.Printf("%T", 100)
// Output: int
Enter fullscreen mode Exit fullscreen mode

Integer verbs

Let’s explore different notation formats for integers. The %x verb lets you convert an integer to a base-16 string. For example, the value 10 is represented by the letter A in the base-16 format.

fmt.Printf("%x", 10)
// Output: a
Enter fullscreen mode Exit fullscreen mode

Another interesting verb is the %U verb, which enables you to convert an integer to its Unicode representation.

fmt.Printf("%U", 10)
// Output: U+000A
Enter fullscreen mode Exit fullscreen mode

Floating-point formatting

Many conversions are possible for floating-point numbers. These conversions are often used to display prices or other numbers with the correct number of digits after the decimal point.

The %e verb, meanwhile, allows you to display a number in scientific notation. A number is written in scientific notation when a number between 1 and 10 is multiplied by a power of 10.

fmt.Printf("%e", 999.35)
// Output: 9.993500e+02
Enter fullscreen mode Exit fullscreen mode

You can convert a number to a floating-point figure with the %f verb. By default, a floating-point number has six digits after the decimal point.

fmt.Printf("%f", 12.3456)
// Output: 12.345600
Enter fullscreen mode Exit fullscreen mode

However, you can use this function more usefully to convert a floating-point figure to a price tag, for example. You can pass in an extra argument that defines the number of decimals.

fmt.Printf("%.2f", 12.3456)
// Output: 12.35
Enter fullscreen mode Exit fullscreen mode

Notice the output here: by default, the fmt package rounds the last digit up.

You can also pass to the %f verb the width for the resulting string. Note that the decimal point also counts for the total width of the string.

In some cases, you might want to have a consistent length for a formatted float or add leading zeroes to your string. Currently, the length of the output 12.35 is five. Let’s set a length of six so that an extra leading zero will be printed.

fmt.Printf("%06.2f", 12.3456)
// Output: 012.35
Enter fullscreen mode Exit fullscreen mode

As you can see, we set the width to six by passing 06 as an extra argument, also called a flag, to the %f verb. You always have to pass a leading zero before setting the width for your string. If you want to set the width of your string equal to 10, for example, you need to pass 010.

fmt.Printf("%010.2f", 12.3456)
// Output: 0000012.35
Enter fullscreen mode Exit fullscreen mode

It’s even possible to set a negative width. Instead of adding leading zeros, you add trailing zeros. However, a negative width does not lend itself well to defining the precision.

fmt.Printf("%-010f", 12.3456)
// Output: 12.345600
Enter fullscreen mode Exit fullscreen mode

There are many more flags you can use to modify the output in combination with the %fverb. You can learn more by reading the fmt docs.

String formatting

Lastly, let’s look at two useful verbs for printing strings. You may encounter escaped strings that look like this: \mystring\. You’ll want to print this string without the escaped syntax so it looks like string. For this, you can use the %s verb.

fmt.Printf("%s\n", "\"string\"")
// Output: "string"
Enter fullscreen mode Exit fullscreen mode

In some cases, you may not want to get rid of the escaped syntax. You can use the %q verb in those instances.

For basic string printing, use %s.

fmt.Printf("%q\n", "\"string\"")
// Output: \"string\"
Enter fullscreen mode Exit fullscreen mode

Also for strings, we can pass flags such as a width for the formatted string. Here, the width of the string is created by adding leading spaces.

fmt.Printf("%10s\n", "five")
// Output:        five
Enter fullscreen mode Exit fullscreen mode

Important notes

Before we end this guide, I should mention a few important points about verbs.

  • If you want to print a %, you can escape it with a percentage sign (you’ll get %%)
  • If you pass a flag such as .2 to a verb that doesn’t expect a flag, it will ignore the flag
  • There are many more string formatting functions besides Printfand Sprintf. You can read about them in the fmt package documentation

Go string literals

String literals enable you to modify a string value to ensure the string is displayed correctly.

For a simple example, let’s say you want to display a value with surrounding double-quotes. You can use a string literal for that. Backticks help encapsulate the double quotes safely.

`"My double-quoted string"`
Enter fullscreen mode Exit fullscreen mode

You can do much more, such as add a line break to your string. For example, if you want to print a list of items with each item on its own line, you can use the \n escape character.

fmt.Println("Items:\n1. Banana\n2. Apple")
// Output: 
Items:
1. Banana
2.Apple
Enter fullscreen mode Exit fullscreen mode

Another way to achieve the same result is with a multiline text block surrounded by backticks. By default, backticks allow you to create multiline strings.

fmt.Println(`
    Items:
    1. Banana
    2. Apple
`)
// Output: 
Items:
1. Banana
2.Apple
Enter fullscreen mode Exit fullscreen mode

Conclusion

Golang offers a rich set of functions, verbs, and flags for converting any type to a string format. The most useful verb is the %+v verb, which enables you to quickly print any object as its string representation. This is very useful for debugging your application.

Personally, I like to use the floating-point formatting options because they offer a range of possibilities for formatting a floating point to the desired string format.


Plug: LogRocket, a DVR for web apps

 
LogRocket Dashboard Free Trial Banner
 
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
Try it for free.


The post Exploring the possibilities of Golang string formatting appeared first on LogRocket Blog.

Top comments (1)

Collapse
 
roelofjanelsinga profile image
Roelof Jan Elsinga

Very interesting post! Do you know how this compares to the strconv package? It has a ParseFloat and Itoa method. Is fmt only used for displaying purposes or also data manipulation?