6 Tips for Using Strings in Go

If you are coming to Go from another language like Ruby or Python there are a lot of changes to take in, and many of these revolve around the string type. Below is a list of some quick tips that answered questions I had during my first few weeks using Golang.

1.Multiline strings

Creating a multiline string in Go is actually incredibly easy. Simply use the backtick (`) character when declaring or assigning your string value.

str := `This is a
multiline
string.`

But be careful - any spacing you use in the string to retain indentation will also be present in the final string.

str := `This string
	will have
	tabs in it`

2.Efficient concatenation

While Go does allow you to concatenate strings with the + operator, this can become pretty inefficient when concatenating a lot of strings together. It is much more efficient to use a bytes.Buffer and then convert it to a string once you have concatenated everything.

package main

import (
	"bytes"
	"fmt"
)

func main() {
	var b bytes.Buffer

	for i := 0; i < 1000; i++ {
		b.WriteString(randString())
	}

	fmt.Println(b.String())
}

func randString() string {
	// Pretend to return a random string
	return "abc-123-"
}

You can also use the strings.Join function if you have all of the strings ahead of time.

package main

import (
	"fmt"
	"strings"
)

func main() {
	var strs []string

	for i := 0; i < 1000; i++ {
		strs = append(strs, randString())
	}

	fmt.Println(strings.Join(strs, ""))
}

func randString() string {
	// Pretend to return a random string
	return "abc-123-"
}

3.Convert ints (or any data type) into strings

In many languages you can easily convert any data type into a string simply be concatenating it with a string, or by using string interpolation (eg "ID=#{id}" in ruby). Unfortunately, if you try to do what seems obvious in Go, like casting an int to a string, you are unlikely to get what you expected.

i := 123
s := string(i)

What would you expect the output of s to be? If you guess "123" like most people would, you would sadly be mistaken. Instead you would get something like "E" as s’s value. That isn’t at all what we wanted!

Instead you should look to use packages like strconv or functions like fmt.Sprintf. For example, here is an example using strconv.Itoa to convert an integer into a string.

package main

import (
	"fmt"
	"strconv"
)

func main() {
	i := 123
	t := strconv.Itoa(i)
	fmt.Println(t)
}

You can also use the fmt.Sprintf function to convert pretty much any data type into a string, but this should generally be reserved for instances where you are actually creating strings with embedded data, not when you want to convert a single integer into a string.

package main

import "fmt"

func main() {
	i := 123
	t := fmt.Sprintf("We are currently processing ticket number %d.", i)
	fmt.Println(t)
}

fmt.Sprintf operates pretty much identically to fmt.Printf except instead of printing out the resulting string to standard output it instead returns it as a string.

4.Creating random strings

This one isn’t really a “quick tip”, but it is a question I see asked a lot.

How do you create random strings in Go?

Sounds simple enough. Many languages like Ruby and Python provide some helpers that make generating a random string really easy, so surely Go has one, right? Wrong.

Go opted to instead only provide the tools to create random strings and left the details up to the developer. While this might be a turn off at first, the upside is that you get to completely dictate how the string is generated. This means you can dictate the character set, how your random generation is seeded, and any other pertient details. In short, you have more control but at the cost of needing to write a little extra code.

Here is a quick example using the math/rand package and a set of alphanumeric characters as the character set.

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	fmt.Println(RandString(10))
}

var source = rand.NewSource(time.Now().UnixNano())

const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

func RandString(length int) string {
	b := make([]byte, length)
	for i := range b {
		b[i] = charset[source.Int63()%int64(len(charset))]
	}
	return string(b)
}

There are likely more optimal solutions than this one for your particular needs, but it is a good starting point. If you are looking for ways to improve/change the code, you might consider using the crypto/rand package for generating random data - this is generally safer, but can end up being more work.

Regardless of what you end up using, this example should help get you started. It works well enough for most practical use cases that don’t involve sensitive data like passwords and authentication systems. Just be sure to remember to seed your random number generator! This can be done in the math/rand package via the rand.Seed function, or by creating a source. I opted to create a source in the example above.

5.The strings package, HasPrefix, and custom code

When dealing with strings it is incredibly common to want to figure out if a string starts with or ends with a specific string. For example, if your API keys all start with sk_ you might want to verify that all API keys provided in an API request start with this prefix, otherwise doing a database lookup is a massive waste of time.

For functions that sounds like very common use cases, your best bet is often to head on over to the strings package and check for something that might help you out. In this case you would want to use the functions strings.HasPrefix(str, prefix) and strings.HasSuffix(str, prefix). You can see them in action below.

package main

import (
	"fmt"
	"strings"
)

func main() {
	fmt.Println(strings.HasPrefix("something", "some"))
	fmt.Println(strings.HasSuffix("something", "thing"))
}

While there are a lot of useful common functions in the strings package, it is worth noting that it isn’t always worth digging around hunting for a package that does what you need. If you are picking up Go after having experience with another language, one common mistake I see is developers spending too much time looking for packages that provide the functionality that they need when they could have easily just written the code themselves.

There are definitely perks to using a standard library; Eg they are tested thoroughly and are well documented. Despite those perks, if you find yourself spending more than a few minute looking for a function it is often just as beneficial to write it yourself. In that case it will be customized for your needs, will be done quickly, and you will completely understand what is happening and won’t be caught off guard by weird edge cases. You also don’t have to worry about someone else maintaining the code.

6.Strings can be converted into byte slices (and vice versa)

The comments on reddit pointed out that the correlation between a string and byte slices isn’t always obvious, so while this article originally started out with 5 tips it has been expanded to 6.

In Go you can convert a string into a byte slice ([]byte) and a byte slice into a string. Doing this is very easy and looks like any other type conversion. This conversion is often performed in order to pass a string into a function that accepts a byte slice, or to pass a byte slice into a function that expects a string.

Below is an example of the conversions:

package main

import "fmt"

func main() {
	var s string = "this is a string"
	fmt.Println(s)
	var b []byte
	b = []byte(s)
	fmt.Println(b)
	for i := range b {
		fmt.Println(string(b[i]))
	}
	s = string(b)
	fmt.Println(s)
}

And that’s it for tips on using strings in Go. I hope you found these helpful and informative, and be sure to check out some of my courses like Gophercises (info below) if you want to practice your Go a bit more.

Just getting started with Go?

Go is an awesome language whether you are new to programming or have experience in other languages, but learning a new language can be a struggle without the right resources.

To help save you time and get you off to a great start, I have created a guide to learning Go that you can get for FREE! Just sign up for my mailing list (down there ↓) and I'll send it to your inbox.

You will also receive notifications when I release new articles and courses that I think will help you our while learning Go.

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.