Compare Strings in Golang: 8 Methods and When to Use Them
Tutorials

Justas Vitaitis
In this article, you will learn which Go string comparison methods you should use for the best performance in each use case. In addition, we will explore how you can combine different methods to achieve the best possible performance, no matter what kind of Golang string comparison you are doing.
If you know how to compare Golang strings, this might seem like a trivial question. You can just pick a method that works and go with it. However, there are significant performance issues in some Golang functions for comparison of strings, and they are there by design.
Therefore, you need to know these caveats to ensure that your code is as fast as it can be.
Let’s explore these methods, see some examples, and you can even test your code live using the links we will provide.
The Best Method to Compare Strings in Golang
There are two clear winners for comparisons in Golang, and there is a clear loser. Additionally, there are other methods used for various purposes. We will discuss in detail the best way to use each of them, but here is a quick summary of all methods we are going to explore today:
- Equality operators (==, !=). The best option for case-sensitive comparison.
- strings.EqualFold(). The best method for case-insensitive comparison.
- strings.Compare(). The worst method for case-insensitive or case-sensitive comparisons.
- len(). This function allows you to compare the size of two strings. It is useful in itself, but also as a performance-enhancing tool for the other functions.
- strings.Contains(). The best method to compare case-sensitive substrings.
- strings.Contains() + strings.ToLower(). The best method to compare case-insensitive substrings.
- Inequality operators (>, <, >=, <=). The best method to compare Golang strings based on their alphabetical order.
Let’s dive into the details now.
len()
Let’s start with a simple yet often forgotten function. len() allows you to compare strings in Golang by their size in bytes. Therefore, if you want to know if a string is bigger than another one, this method is the way to go.
Here is a simple way to use it:
package main
"fmt"
func main {
var stringA "John"
var stringB = "Paul"
if lenstringA == lenstringB) {
fmtPrintln"The size is the same"
} else {
fmt.Println"The size is different"
}
// Result: The size is the same
stringA = "Ringo"
stringB "George"
if lenstringA == lenstringB) {
fmtPrintln("The size is the same"
}
if lenstringA < lenstringB {
fmt.Println("A is smaller than B")
} else {
fmt.Println("A is bigger than B")
}
// Result: A is smaller than B
}
The len() function is quite useful for improving the other functions as well. When you run a comparison function such as “==”, Go compares characters one by one. This process takes quite some time.
But checking the string's size is really fast with len(). Therefore, you can add a test to see if the string sizes are the same before running other equality tests. This allows you to reduce processing times whenever the strings are different.
Let's see how it works in real examples with each of the functions.
Go String Equality Check Using == and !=
The equality operators allow you to check if a string is equal to or different from another. It checks for an exact match, so it is case-sensitive. It is the fastest option for case-sensitive comparisons, and is recommended by the Golang team.
You can combine the equality operators with the len() function for even better performance. In this case, you check if the strings are the same size first, and then you run the equality operators on the string's contents.
Golang Case-Insensitive String Comparison
If you want to use the equality operators in case-insensitive comparisons, you can use the strings.ToLower() function to convert all characters to lowercase and then check if two strings are equal. You don't need to do it, though. The EqualFold() function is a better option for such comparisons.
Here are some examples of how you can use the equality operators to compare Golang strings:
package main
"fmt"
"strings"
func main {
var stringA "John"
var stringB = "Paul"
stringA == stringB {
fmtPrintln"John is Paul"
} {
fmtPrintln"John isn't Paul"
}
// Result: John isn't Paul
stringA = "John"
stringB = "john"
if stringA == stringB {
fmt.Println"John is john"
} else {
fmtPrintln"John isn't john"
}
// Result: John isn't john
stringA "John"
stringB = "john"
if stringsToLowerstringA == strings.ToLowerstringB {
fmtPrintln"John is john when converted to lowercase")
} else {
fmt.Println"John isn't john when converted to lowercase")
}
// Result: John is john when converted to lowercase
}
stringA "John"
stringB = "John Lennon"
if len(stringA == len(stringB {
if stringA == stringB {
fmtPrintln"The sizes are the same, but John isn't John Lennon"
} else {
fmt.Println"The sizes are the same, and John is John Lennon")
}
} else {
fmtPrintln"The sizes are different"
// Result: The sizes are different
The Inequality Operators ( >, <, >=, <=)
When comparing numbers, it’s quite simple to understand what these operators mean. But when it comes to strings, they behave in a special way.
If you use the inequality operators to compare Golang strings, you are comparing the dictionary order of these strings. You’ll often see the technical docs refer to it as lexicographic order . That’s the same concept as dictionary order, which can be tricky when comparing strings with numbers and letters.
Notice that a lower order means that a number comes first in the dictionary. So “abc” has a lower order than “def”. Also, upper case letters come before lowercase letters. So “ABC” has a lower order than “abc”, which means that “ABC” comes first in the dictionary.
Here’s how it works:
// IPRoyal Golang string compare examples
package main
import
"fmt"
)
func main {
var stringA = "John"
var stringB = "john"
if stringA < stringB {
fmtPrintln("John comes before john")
} else {
fmtPrintln("John doesn't come before john")
}
// Result: John comes before john - uppercase letters come first
stringA = "Johnny"
stringB = "John Lennon"
if stringA < stringB {
fmtPrintln("Johnny comes before John Lennon")
} else {
fmtPrintln"Johnny doesn't come before John Lennon"
}
// Result: Johnny doesn't come before John Lennon - smaller words come first
stringA "10 John"
stringB = "2 John"
if stringA < stringB {
fmtPrintln"10 John comes before 2 John"
} else
fmt.Println("10 John doesn't come before 2 John")
// Result: 10 John comes before 2 John - Even though 10 is bigger than 2, it is a dictionary comparison so 1 comes before 2
}
strings.Compare()
Let's be clear, even the Golang team says that this function shouldn't be used at all. Here is what they have in the comparison declaration:
func Comparea b string) int {
// NOTE(rsc): This function does NOT call the runtime cmpstring function,
// because we do not want to provide any performance justification for
// using strings.Compare. Basically no one should use strings.Compare.
// As the comment above says, it is here only for symmetry with package bytes.
// If performance is important, the compiler should be changed to recognize
// the pattern so that all code doing three-way comparisons, not just code
// using strings.Compare, can benefit.
...
}
Anyway, if you do want to use it, or if you want to see how it works to refactor some old code, the general idea is that this function performs case-sensitive comparison. But instead of returning a true/false result, it returns zero if they are equal or the lexicographically (dictionary) comparison of the two strings.
Therefore, it is similar to running the equality operator (with “different than”), and if the strings are different, running the inequality operator. Here are the possible return values for strings.Compare( stringA, stringB ):
- if stringA == stringB, return 0
- if stringA > stringB, return 1 - meaning that A is after B in the dictionary
- if stringA < stringB, return -1 - meaning that A is before B in the dictionary
You can see it in action here:
package main
import (
"fmt"
"strings"
func main() {
var stringA = "John"
var stringB = "John"
fmtPrintlnstrings.ComparestringA, stringB
// Result: 0 - both are equal
stringA = "John"
stringB "john"
fmtPrintln(strings.ComparestringA stringB))
// Result: -1 - John comes first in the dictionary
stringA "Johnny"
stringB = "John Lennon"
fmtPrintln(stringsComparestringA stringB))
// Result: 1 - John Lennon comes first in the dictionary
stringA "10 John"
stringB = "2 John"
fmt.PrintlnstringsCompare(stringA, stringB
// Result: -1 - 10 John comes first in the dictionary
}
The strings.Compare() function is often avoided not only because it’s not recommended, but also due to its poor runtime performance compared to other comparison operators, such as ==.
Here’s a quick time complexity overview:
- == Operator: O(n). Compares each character, short-circuits on first mismatch.
- strings.Compare(): O(n). Similar in time complexity, but adds overhead due to extra function calls and return logic.
Below is a small benchmark test comparing == with strings.Compare():
// golang compare strings micro-benchmark
package main
import (
"fmt"
"strings"
"testing"
)
func BenchmarkEqualOperator(b *testing.B) {
a := "The Beatles were: John, Paul, George, Ringo"
c := "The Beatles were: John, Paul, George, Ringo"
for i := 0; i < b.N; i++ {
_ = a == c
}
}
func BenchmarkCompareFunction(b *testing.B) {
a := "The Beatles were: John, Paul, George, Ringo"
c := "The Beatles were: John, Paul, George, Ringo"
for i := 0; i < b.N; i++ {
_ = strings.Compare(a, c)
}
}
This happens because the compiler can optimize the equality operator much more effectively than a function call. So if you’re after speed, stick with ==.
Note: there may be a bug in Windows PowerShell where it will not properly recognize go test -bench=. in some cases. Use go test -bench=Benchmark in that case.
strings.Contains()
You can check if one string is present in its entirety inside another string with the contains function. This is a case-sensitive comparison.
It returns true if the string contains the other and false if not. To remember the order of the arguments, notice that you can translate the code “Contains( a, b )” as “does ‘a' contains ‘b` ?”, thus A is the bigger string, and B is the substring you are testing.
Here is how it works:
package main
"fmt"
"strings"
func main {
var stringA "The Beatles were an amazing band"
var stringB = "John"
fmtPrintlnstringsContains(stringA stringB))
// Result: false
stringA = "The Beatles were: John, Paul, George, Ringo"
stringB = "John"
fmtPrintlnstrings.Contains(stringA, stringB)
// Result: true
stringA = "The Beatles were: John, Paul, George, Ringo"
stringB = "john"
fmtPrintlnstringsContainsstringA stringB)
// Result: false
}
Strings.Contains() + strings.ToLower()
Out of the box, the contains function is case-sensitive. If you need to compare if a string contains another substring ignoring their case, you can convert both to lowercase prior to your comparison.
Check out some examples:
// IPRoyal Golang string compare examples
package main
(
"fmt"
"strings"
)
func main() {
var stringA = "The Beatles were an amazing band"
var stringB = "John"
fmtPrintln(stringsContains(stringsToLowerstringA, stringsToLowerstringB))
// Result: false
stringA "The Beatles were: John, Paul, George, Ringo"
stringB "John"
fmtPrintlnstrings.Contains(strings.ToLower(stringA) strings.ToLowerstringB)
// Result: true
stringA = "The Beatles were: John, Paul, George, Ringo"
stringB "john"
fmtPrintlnstrings.ContainsstringsToLower(stringA, strings.ToLowerstringB))
// Result: true
}
Using strings.HasPrefix() and strings.HasSuffix()
Sometimes, you only need to know if a string starts or ends with another. In such cases, strings.HasPrefix() and strings.HasSuffix() are great tools. These are also case-sensitive.
// IPRoyal Golang string compare examples
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.HasPrefix("GoLang Rocks", "Go")) // true
fmt.Println(strings.HasSuffix("GoLang Rocks", "Rocks")) // true
fmt.Println(strings.HasPrefix("GoLang Rocks", "rocks")) // false (case-sensitive)
fmt.Println(strings.HasSuffix("GoLang Rocks", "Lang")) // false
// Edge cases
fmt.Println(strings.HasPrefix("", "")) // true
fmt.Println(strings.HasSuffix("", "")) // true
fmt.Println(strings.HasPrefix("A", "")) // true
fmt.Println(strings.HasSuffix("A", "")) // true
}
These methods are especially helpful in string filtering logic or validating inputs.
Conclusion
Today you've learned the best Go string comparison methods. In addition, you learned how you can combine the best-performing methods with other Golang functions to achieve the best performance possible.
By the end of the day, you should be able to compare your strings by their contents, size, dictionary order and substrings.
We hope you've enjoyed it. If you haven't already, make sure to check our guide on how to build a Golang web scraper . See you again next time!
FAQ
Can you use == for strings in Golang?
Yes, you can use the equality comparison for strings in Golang. It looks for an exact match, so it is a case-sensitive search.
If you require a case-insensitive method, consider using strings.EqualFold() since it is more performant for that task. Alternatively, you could use the strings.ToLower() method, but it won't be as fast.
You shouldn't use the strings.Compare() function, as it isn't recommended by the Golang team and it is significantly slower than its alternatives.
How do you find the length of a string in Golang?
You can use len() to find the byte size of a string. This can lead to unpredictable results if you are using some characters that occupy more than one byte. If you want to know the number of characters in a string, you can use len([]rune(string), such as len([]rune(“abc”).
How do I convert an int to a string in Golang?
You can use the strconv function. In it, you can use the Itoa method for a direct conversion of base 10 integers, such as strconv.Itoa(number), or you can use the FormatInt method to convert from different bases, such as strconv.FormatInt(number, 10).
How would you confirm that two strings have the same identity?
In Golang, string identity means both strings point to the exact same content. Use == to compare string values for equality. Go strings are immutable values, so if a == b returns true, they contain the same sequence of bytes. There’s no pointer-level identity check exposed to developers like in some other languages.
Can we use the if function to compare Golang strings?
Yes, you can use an if statement like this:
if a == b {
fmt.Println("They are the same.")
}
It uses comparison operators to check if strings are equal. It works for most use cases.
How to compare string to substring?
Use strings.Contains() when checking if a substring exists within a string. If you want to check from the start or end, use strings.HasPrefix() or strings.HasSuffix().
These methods check for substring presence or structural match, but do not compare Golang strings lexicographically.
How do you compare two string arrays?
You can loop through each element and use == on each item:
func compareStringArrays(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
You can also use reflect.DeepEqual() from the reflect package, but it’s slower. However, since Go 1.21, you can use slices.Equal():
goimport "slices"
func compareStringArrays(a, b []string) bool {
return slices.Equal(a, b)
}
This is more idiomatic and likely more performant than the manual loop.