10 minutes read

String formatting helps us save time to solve complicated tasks.

For example, if we need to print the hex value of a decimal number 100000 (which is 186a0) to the console, normally we wouldn't input this value by hand. We can solve this task more conveniently with string formatting.

In this topic, we'll learn how to use string formatting in Go. Overall, there are two ways to do this:

  • Printing a formatted string with the Printf() function;

  • Formatting and returning the string by using the Sprintf() function instead of printing it to the console.

Both methods are in the fmt package.

Introduction to fmt.Printf()

fmt.Printf() accepts at least one argument. Our first option is to use fmt.Printf as an alternative to fmt.Print:

fmt.Printf("kitty1\nkitty2")
fmt.Printf("\n")
fmt.Printf("kitty1\tkitty2")
// kitty1
// kitty2
// kitty1  kitty2

However, in most cases, we pass two or more arguments tofmt.Printf(). The first one is the string template that contains the text that we want to format, together with one or more verbs (or format specifiers) that specify how we want the string template to be formatted. All remaining arguments are variables that store the value of what we want to format.

For example, look at the following code snippet:

s := "Golang"
a := "young"
fmt.Printf("We are %s hackers, we are so %s", s, a) // We are Golang hackers, we are so young

Note that other functions in the fmt package that end with the f character usually have the format string functionality.

Formatting strings with different verbs

In this section, we are going to consider different format specifiers that we can use to format strings.

Let's begin with numeric values. Take a look at the following examples:

// Using %d to print an int value
fmt.Printf("%d", 36) // 36

When using this verb, we can specify the precision field length by a decimal number. To do this, we need to put a dot and then the precision length, like in the example below. If we don't specify a special value, Printf() will use the default value of the width and the precision length:

// Using %f to print a float value with default width and precision
fmt.Printf("%f", 20.66) // 20.660000

// Using %f with the precision length 1
fmt.Printf("%.1f", 20.33) // 20.3

Now, this is how we format strings, characters, and boolean values:

// The %c formatter is used to format a single character
letter := 't'
fmt.Printf("%c", letter) // t
secret := '🤫'
fmt.Printf("%c", secret) // 🤫

// The %s formatter is great to format a string
fmt.Printf("%s", "This is a random string") // This is a random string

// The %t formatter is suitable for Boolean values
fmt.Printf("%t", false) // false

And this is how we format the width of string values:

// Formatting the width of a string
fmt.Printf("|%8s|", "pikachu") // | pikachu| (this action added one additional space where the string begins)

Finally, we can use the %% verb to print a raw "%" string:

fmt.Printf("%%") // %

Explicit argument indexes

Now, sometimes we might need to use a variable more than once or format multiple variables in a different order. We can do it by using [] square brackets.

The number inside the square brackets [] between the % character and the verb denotes the replacement of the corresponding variable when formatting the string. This means we can use this symbol to express how many times a variable appears or change the order of the variables when formatting a string:

a := "First variable"
b := "Second variable"
fmt.Printf("%[1]s | %[1]s \n", a) // First variable | First variable
fmt.Printf("%[2]s | %[1]s", a, b) // Second variable | First variable

Default verb %v

It is important that we learn about one more verb — the default verb %v. We can use it in many cases, such as printing the Unicode number of an emoji or non-English characters, printing the raw form of an array or a slice in Go, or formatting complex numbers. In short, you can format all objects in Go as strings in some way, but in case we don't know how to format them without errors using a built-in verb, we can always pass them to %v:

fmt.Printf("%v",'😄') // 128516 (Unicode number)

fmt.Printf("%v", "世界") // 世界 (means "world" in Chinese)

fmt.Printf("%v", []int{1, 2, 3, 4, 5, 6}) // [1 2 3 4 5 6]

fmt.Printf("%v", [3]int{9, 8, 7}) // [9 8 7]

fmt.Printf("%v", 1+5i)// 1+5i (this is a complex number)

Take notice that there are many other formatting verbs in Go! If you want to know more about them you can take a look at the verbs section in the official Go docs.

Other functions in the fmt package: Sprintf(), Print(), Sprint(), Println(), Sprintln()

We can create and return strings using Sprintf(). This function creates formatted strings without directly printing them:

first := fmt.Sprintf("%d", 500) // 'first' variable now has the value of 500

binaryVariable := fmt.Sprintf("%b", 500) // 'binaryVariable' variable now has the value of 111110100

Print(), Sprint(), Println(), Sprintln() use the default verb %v, so we don't need to add any additional string templates or verbs with them.

All these functions can take more than one argument, and the string format in this case will be concatenated.

If the function name has the prefix S, it means these functions will return the formatted string as the data object instead of directly printing it to the console. And if the function name has the suffix ln, it means the function will add an additional newline character \n at the end of the formatted string.

Below is an example of the Print() function:

fmt.Print("Hello") // Hello

x := "World"

fmt.Print("Hello, ", x) // Hello, World

And here's an example of a function that ends with the ln suffix:

s := fmt.Sprintln("if you try to print s,",
                  "it will automatically print a new line at the end of the string")

fmt.Print(s, "Newline")

/*
Output:
if you try to print s, it will automatically print a new line at the end of the string
Newline
*/

Formatting multiline string with back quotes

Additionally, we can use raw string literals by wrapping string sequences between back quotes `...`.

This technique can help us easily write multiline formatted strings. Notice that special characters like \n newline will not be interpreted within raw string literals:

fmt.Printf(`%s 
and
the
brave
new\n
world\n`,"Go")

/*
Output:
Go 
and
the
brave
new\n
world\n
*/ 

Conclusion

In this topic, we've learned that Golang has many built-in functions to format strings. They are all included in thefmt package. We've covered the fmt.Printf() and fmt.Sprintf() functions, as well as different verbs we can use to format strings. We've also looked at the Print(), Sprint(), Println(), Sprintln() functions and when we use them.

In practice, formatting strings properly can be very useful, as it allows us to make our code neat and readable. Let's do some exercises now to make sure this information stays with us!

107 learners liked this piece of theory. 1 didn't like it. What about you?
Report a typo