Substring
In the Go language, no substring func
is available. Instead we access parts of strings (substrings) with slice syntax.
To take a substring in this language, we specify a first index and a last index. The first integer is a start index. And the second is an end index.
There are 2 ways to take a slice of a string
. We can convert a string
to a rune
slice, and then take a slice of the runes. Or we can take a slice of the string
directly.
string
to a rune
slice and then operate on the runes.byte
characters, we can use the slice syntax directly on a string
. This should be used with care.char
substring.package main import "fmt" func main() { // A string. value := "bird" // Part 1: take substring with runes. // ... This handles any kind of rune in the string. runes := []rune(value) // ... Convert back into a string from rune slice. safeSubstring := string(runes[1:3]) fmt.Println(" RUNE SUBSTRING:", safeSubstring) // Part 2: take substring with direct byte slice. // ... This handles only ASCII correctly. asciiSubstring := value[1:3] fmt.Println("ASCII SUBSTRING:", asciiSubstring) } RUNE SUBSTRING: ir ASCII SUBSTRING: ir
For non-ASCII characters, more than 1 byte
is required for a character. To take substrings correctly on non-ASCII strings, we must use runes.
rune
slice of a string
correctly handles some characters. This is important for many applications.package main import "fmt" func main() { // This string contains Unicode characters. value := "ü:ü" // Convert string to rune slice before taking substrings. // ... This will handle Unicode characters correctly. // Not needed for ASCII strings. runes := []rune(value) fmt.Println("First 1:", string(runes[0:1])) fmt.Println(" Last 1:", string(runes[2:])) }First 1: ü Last 1: ü
Here we take a slice (a substring) of a string
. We start at the index 4, which is the letter "d." And this proceeds until the end of the string
.
string
, we can use the len
built-in. This means "to the end" of the string
.package main import "fmt" func main() { value := "cat;dog" // Take substring from index 4 to length of string. substring := value[4:len(value)] fmt.Println(substring) }dog
The first index of a slice can be omitted. This always means the index 0. So if you don't like typing 0, this is a good thing.
package main import "fmt" func main() { value := "abcd" // Omit start index, this is the same as zero. // ... Take 2-char substring. substring := value[:2] // Test the substring. if substring == "ab" { fmt.Println(true) } }true
We can omit the end index. This takes the substring from a start index to the end of the string
. This is a clearer way of using the length as the end.
package main import "fmt" func main() { value := "frog;fish" // We can specify just the start index. substring := value[5:] fmt.Println(substring) }fish
In Go, we can use "full slice expressions" with three indexes on some types. The third index is a max index (so the slice does not go off the end).
package main import "fmt" func main() { value := "one two" // This program does not work. // ... String slice cannot have three indexes. result := value[4:8:6] fmt.Println(result) }# command-line-arguments invalid operation value[4:8:6] (3-index slice of string)
When taking substrings, it is important to ensure we are within the bounds of the string
. If our first or last index is out of range, a panic will occur.
len
built-in method, along with some if
-tests, can solve these runtime errors.package main import "fmt" func main() { value := "abc" // Indexes must be validated first or a panic occurs. result := value[10:20] fmt.Println(result) }panic: runtime error: slice bounds out of range goroutine 1 [running]: main.main() C:/programs/file.go:11 +0x144.... exit status 2
To review, Go does not provide a substring()
method. But with slice syntax, we take substrings based on the first and last index. We must first check indexes to prevent panics.