Search code examples
stringgosubstring

Why doesn't golang have substring?


Can i do something like prototyping in javascript in Golang so i can at least do something like:

string.substring(0,7) 

or am i forced to use my function here?:

func substring(str string, start int, length int) string {
    return string([]rune(str)[start:length+start])
}

Solution

  • Substrings is a "thing" in Go too: slicing a string results in a string which shares memory with the original string.

    The difference is that in Go the indices are byte-indices, not character or rune indices. Go stores the UTF-8 encoded byte sequence of texts in a string.

    If your input consists of ASCII characters only (byte values less than 128), then using byte indices is the same as using rune indices:

    s := "abcdef"
    fmt.Println(s[1:3])
    

    This will output:

    bc
    

    If your input may contain multi-byte unicode characters, then you have to decode the (UTF-8) bytes of the string. For that, there is the standard unicode/utf8 package, or you may use for range over the string which does the same thing.

    The for range over the string decodes the bytes, and each iteration "yields" one rune of the string, and also returns the starting byte position of the rune.

    This is how we can use that to construct a substr() function:

    func substr(s string, start, end int) string {
        counter, startIdx := 0, 0
        for i := range s {
            if counter == start {
                startIdx = i
            }
            if counter == end {
                return s[startIdx:i]
            }
            counter++
        }
        return s[startIdx:]
    }
    

    substr() takes a string and a start (inclusive) and end (exclusive) rune indices, and returns a substring according to that. Checks (like start <= end) are omitted for brevity.

    Testing it:

    s := "abcdef"
    fmt.Println(substr(s, 1, 3))
    
    s = "世界世界世界"
    fmt.Println(substr(s, 1, 3))
    fmt.Println(substr(s, 1, 100))
    

    Output (try it on the Go Playground):

    bc
    界世
    界世界世界