Concatenating and Building Strings in Go 1.10+

Go 1.10 introduced the new strings.Builder type, which can be used to efficiently and easily build or concatenate strings. In this post we explore some of the ways to use the type as well as why it implementing the io.Writer interface makes it an incredibly powerful tool. Most of this information could be found on the official docs, but the examples here are intended to get you up and running a tad faster while also illustrating some of the non-obvious implications.

Creating your first string with strings.Builder

The most obvious use case, especially amongst beginners, is to simply want to concatenate some strings together. For instance, you may want to take all the elements of a slice and manually add them to a string. Without the strings.Builder you might write some code like below.

func join(strs ...string) string {
	var ret string
	for _, str := range strs {
		ret += str
	}
	return ret
}

While this works perfectly fine for a simple program, it is a little inefficient. Every time we call ret += str a brand new string needs to be allocated in memory. This happens because strings in Go are immutable, so if we want to change a string or add contents to it we need to create an entirely new string. To avoid creating new strings as we build our final string, we can now use the strings.Builder type along with its WriteString method.

func join(strs ...string) string {
	var sb strings.Builder
	for _, str := range strs {
		sb.WriteString(str)
	}
	return sb.String()
}

Similarly, you can use the WriteRune and WriteByte methods to add single characters to your string as you build it.

func joinRunes(runes ...rune) string {
	var sb strings.Builder
	for _, r := range runes {
		sb.WriteRune(r)
	}
	return sb.String()
}

Once you are done building a specific string you can also reset your builder and then make use of it to build a new string.

func joinedAndReverse(strs ...string) (string, string) {
	var sb strings.Builder
	for _, str := range strs {
		sb.WriteString(str)
	}
	joined := sb.String()
	sb.Reset()
	for i := len(strs) - 1; i >= 0; i-- {
		sb.WriteString(strs[i])
	}
	return joined, sb.String()
}

string.Builder also implements the io.Writer interface

In addition to providing the WriteString, WriteRune, and WriteByte methods, the string builder also implements the io.Writer interface. At first this may not seem very important - why would we want to write a byte slice when we could just write a string? - but because the string builder implements the io.Writer interface it means that we can use functions like fmt.Fprintf along with the string builder. This is demonstrated with the string builder example in the standard docs.

var b strings.Builder
for i := 3; i >= 1; i-- {
	fmt.Fprintf(&b, "%d...", i)
}
b.WriteString("ignition")
fmt.Println(b.String())

Of course, you can always use the bytes.Buffer that has been around and is discussed in the article, 6 Tips for Using Strings in Go.

Learn Web Development with Go!

Sign up for my mailing list and I'll send you a FREE sample from my course - Web Development with Go. The sample includes three chapters from the book, and over 2.5 hours of screencasts.

You will also receive notifications when I release new articles, along with other freebies that I only share with my mailing list.

Avatar of Jon Calhoun
Written by
Jon Calhoun

Jon Calhoun is a full stack web developer who also teaches about Go, web development, algorithms, and anything programming related. He also consults for other companies who have development needs. (If you need some development work done, get in touch!)

Jon is a co-founder of EasyPost, a shipping API that many fortune 500 companies use to power their shipping infrastructure, and prior to founding EasyPost he worked at google as a software engineer.

Related articles

Spread the word

Did you find this page helpful? Let others know about it!

Vote on Hacker News

Sharing helps me continue to create both free and premium Go resources.

Want to discuss the article?

See something that is wrong, think this article could be improved, or just want to say thanks? I'd love to hear what you have to say!

You can reach me via email or via twitter.

Recent Articles All Articles Mini-Series Tags About Me Go Courses

©2018 Jonathan Calhoun. All rights reserved.