Strings in Golang: Common Mistakes and Best Practices

Reza Khademi
5 min readSep 18, 2023

In this story we want to discuss about strings in Golang and see some different scenarios to avoid common mistakes. Let’s dive in!

1. strings can be nil or not?

We already have a fundamental knowledge about strings in Golang but a good point to start is Golang strings cannot be nil, unless you use a pointer to strings.

When we creating a string variable as shown below the default value must be empty "". If we initialize it with nil value, we will face with cannot use nil as string value in variable declaration error. For example:

So, we can let the Golang initialize them for us or use "" as default value:

strings in golang default value of variables
Note the output is empty

If we insist to have a nil value in a string type variable, we should use pointers as below:

Note the output is nil

However we have to be careful with this approach. Every time we want to assign a value to the name variable we have to write more codes and also check for a nil or previous value before assigning the new value. Take a look at this:

So, normal strings are easier and safer to use in Go.

2. strings are immutable

Strings in Golang are immutable and that means we can not change the value of each characters. For example:

The above code would result in compile-time error as cannot assign to temp[0].

A common mistake about changing an individual character of a string is as below:

Although the displayed result is what we expected, this is not the correct way to change a certain character.

This is because the single part we intend to modify could be stored in multiple bytes and even if you are thinking about converting the variable to rune type and mutate the part you want, I have to say, that it cannot be done, again because it could be placed in multiple runes and we need to move with caution!

3. strings are bytes

In Golang, strings are made up of bytes (slice of bytes) and some characters need to store in multiple bytes e.g: "♥"

So, when there is a need to determine length of a variable with the type of string, we must code carefully. For example:

The len function returns the number of bytes in a string, not the number of characters and when we need to find out the number of runes of a string, we could use uft8.RuneCountIntString().

Another common misunderstand is to use uft8.RuneCountIntString() to determine number of characters, but it’s not correct in every situation because a string variable might be spanned between multiple rune. Look at this example:

4. strings index and range

In Golang, retrieving an individual part of a string by using its index will provide us with the uint value of the character and will only retrieve the first byte. However Inside a for loop on a string variable, we have access to the rune value of each character:

strings in golang Indexing and Ranging

Another quick note when iterating over a string is being aware of non-UTF8 characters which may exist in our variables and if Golang can’t understand it as UTF8, will use a unicode replacement not the actual value.

Because of that, it might be better to use a for loop like below when we are dealing with strings in golang that have non-UTF8 characters:

This way, we will prevent any data change and always using actual value.

5. strings equality

We can always use a == to check for simple strings equality in Golang but if there is a hidden spot on our variables we should use unicode norm package to normalize them before comparing two string variables:

check strings equality

6. efficient string building

Concatenating a large number of strings could be very inefficient. One of the best practices to compose strings efficiently is by using strings.Builder:

strings in golang efficient string building

This approach is way more faster and less memory consumption than the classic + concatenating method and it will avoid the creation of unnecessary intermediate string. Also we can achieve this goal with bytes.Buffer package.

That’s it. Here is the summary of what we have reviewed so far.

Summary

  • Strings default value is ""
  • The len and RuneCountIntString functions have different behaviors
  • We should be careful about for loops and strings
  • Strings equality is where we need to be more accurate

If you like this article please Clap 👏 and follow me to get more of these Golang contents.

ALSO READ:

--

--