What is string in Go?
In Go (Golang), a string is a sequence of Unicode characters and serves as a built-in data type for representing text.
Strings in Go are immutable, meaning that once a string is created, its contents cannot be changed directly.
Although you can manipulate strings using various functions, these operations always produce new strings rather than modifying the original ones.
Internally, a string is a read-only slice of bytes, and it is stored as two components:
- a pointer to underlying data
- and its length\
Essential Properties of Strings in Go
Immutable Nature
Strings in Go are immutable, which means that once a string is created, it cannot be changed. Any attempt to modify a string results in the creation of a completely new string.
Default UTF-8 Encoding
By default, strings in Go are stored using UTF-8 encoding, which allows them to handle Unicode characters seamlessly.
Byte-Based Length
The length of a string in Go is calculated based on the total number of bytes it contains, rather than the count of individual characters (runes). This is because a single character can be represented by multiple bytes in UTF-8 encoding.
String Declaration
You can declare strings in Go using double quotes ("") for plain strings or backticks (`) for raw strings.
import "fmt"
func main() {
plainString := "Hello world!"
fmt.Println(plainString) // Hello world!
// Raw string supports multiline and includes
// escape characters
rawStr := `This is a raw
string "literal" with\n a new line
`
fmt.Println(rawStr)// This is a raw string "literal" with
// a new line
}
Common String operations
Length of a string
import "fmt"
func main() {
str := "Hello world!"
fmt.Println(len(str)) // 12
rawStr := `This is a rawString "literal" with
a new line
`
fmt.Printf("%s", rawStr)
// This is a rawString "literal" with
// a new line
}
Accessing runes
A rune is an alias for int32 amd is used to represent individual characters. A rune can be made up of 1 to 3 int32 values. This allows for both single and multibyte characters. String can be accessed like a slice to get individual bytes.
import "fmt"
func main() {
r := 'A'
fmt.Printf("%v (%T) %s", r, r, string(r))
// 65 (int32) A
S := `hello`
fmt.Printf("%v (%T) %s", S[1], S[1], string(S[1]))
// 101 (uint8) e
}
String Concatenation
Use the +
operator to concatenate strings
import "fmt"
func main() {
str := "adios, arrivederci"
strRest := "bye bye, sayonara"
fmt.Println(str + ", " + strRest)
// adios, arrivederci, bye bye, sayonara
mergedStr := fmt.Sprintf("%s, %s", str, strRest)
fmt.Println(mergedStr)
// adios, arrivederci, bye bye, sayonara
}
Substrings
Use slicing to extract substrings for simple strings that don't contain special symbols. This approach slices the bytes, not the runes.
import "fmt"
func main() {
start := 0
end := 5
str := "Hello world!"
fmt.Println(str[start:end])
// in case of Unicode occurrences
str2 := "not ASCII δΈηπΆβπ«οΈγγγ«γ‘γ―δΈη"
runes := []rune(str2)
fmt.Println(string(runes[start:])) // SCII δΈηπΆβπ«οΈγγγ«γ‘γ―δΈη
}
Iterating over a string
Use for to iterate over bytes
import "fmt"
func main() {
str := "Hello γγγ«γ‘γ―δΈη"
// In Go, range over a string iterates over Unicode code points (runes), not bytes.
for _, c := range str {
fmt.Printf("%c", string(c)) // Hello γγγ«γ‘γ―δΈη
}
// str[i] will give you the byte at index i, which means this loop is iterating over
// each byte of the string individually.
for i := 0; i < len(str); i++ {
fmt.Printf("%c", str[i]) // Hello γγγ«γ‘γ―δΈη
}
}
Convert between strings and byte slices
String can be converted to byte slices and vice versa
import "fmt"
func main() {
str := "Hello γγγ«γ‘γ―δΈη"
b := []byte(str) // convert to byte slice
fmt.Println(b) // [72 101 108 108 111 32 228 184 150 33]
// Convert byte slice back to string
newStr := string(b)
fmt.Println("Converted back to string:", newStr)
}
Performance Considerations
Converting a string to a []byte or []rune has a performance cost. Use it carefully in performance-critical applications. For heavy string manipulations, consider working directly with []byte or []rune to avoid repeated conversions.
String Comparison in Go
In Go, comparing strings is straightforward and efficient. The language provides built-in operators and functions to handle string comparison tasks. Hereβs what you need to know:
Comparing Strings with Operators
Go allows you to use the standard comparison operators (==, !=, <, <=, >, >=) for strings. These comparisons are lexicographical, meaning they compare the strings byte by byte in Unicode code point order.
import "fmt"
func main() {
str1 := "apple"
str2 := "banana"
fmt.Println(str1 == str2) // false
fmt.Println(str1 != str2) // true
fmt.Println(str1 < str2) // true (lexicographical order)
fmt.Println(str1 > str2) // false
str1 = "Hello"
str2 = "hello"
// Case-sensitive comparison
fmt.Println(str1 == str2) // false
// Case-insensitive comparison
fmt.Println(strings.EqualFold(str1, str2)) // true
}
Sorting Strings
Since Go compares strings lexicographically, you can use these operators to sort strings.
import (
"fmt"
"sort"
)
func main() {
fruits := []string{"banana", "apple", "cherry"}
sort.Strings(fruits)
fmt.Println(fruits) // [apple banana cherry]
}
String comparison in Go is simple yet powerful. Whether you need to check equality, sort data, or validate user input, Go provides the tools to handle it efficiently and effectively. Just remember: Go compares strings byte by byte, so consider using case-insensitive methods when needed!
Conclusion
Strings in Go are a versatile and essential aspect of the language, providing robust features for text handling. Their immutable nature, UTF-8 encoding, and powerful built-in functions make strings both simple to use and efficient. Whether you are manipulating, comparing, or iterating over strings, Go equips you with the necessary tools to handle them effectively.
As you delve into more complex applications, remember that performance is crucial. Pay attention to conversions between strings, bytes, and runes, especially in performance-critical scenarios. With this foundational understanding, youβre equipped to utilize Goβs string capabilities like a professional!
As always, take care in that coding journey, and Iβll catch you next time! π€