如何在防止“切片边界超出范围”错误的同时轻松地在 Go 中获取子字符串?

使用 Go,我想将长字符串截断为任意长度(例如用于日志记录)。


const maxLen = 100


func main() {

    myString := "This string might be longer, so we'll keep all except the first 100 bytes."


    fmt.Println(myString[:10])      // Prints the first 10 bytes

    fmt.Println(myString[:maxLen])  // panic: runtime error: slice bounds out of range

}

现在,我可以用一个额外的变量和if语句来解决它,但这似乎很冗长:


const maxLen = 100


func main() {

    myString := "This string might be longer, so we'll keep all except the first 100 bytes."


    limit := len(myString)

    if limit > maxLen {

        limit = maxLen

    }


    fmt.Println(myString[:limit]) // Prints the first 100 bytes, or the whole string if shorter

}

有没有更短/更清洁的方法?


qq_遁去的一_1
浏览 210回答 2
2回答

慕村9548890

使用一个简单的函数来隐藏实现细节。例如,package mainimport "fmt"func maxString(s string, max int) string {    if len(s) > max {        r := 0        for i := range s {            r++            if r > max {                return s[:i]            }        }    }    return s}func main() {    s := "日本語"    fmt.Println(s)    fmt.Println(maxString(s, 2))}输出:日本語日本

汪汪一只猫

假设您想保留最多的maxLen字符,即您的代码所说的内容,而不是您的字符串所说的内容。如果你不需要原来的 myString,你可以像这样覆盖它:const maxLen = 100func main() {    myString := "This string might be longer, so we'll keep the first 100 bytes."    if len(myString) >= maxLen {        myString = myString[:maxLen] // slicing is a constant time operation in go    }    fmt.Println(myString) // Prints the first 100 bytes, or the whole string if shorter}这可能会将 unicode 字符减半,最后留下一些垃圾。如果您需要处理多字节 unicode(您可能会这样做),请尝试以下操作:func main() {    myString := "日本語"    mid := maxLen    for len(myString) >= mid && utf8.ValidString(myString[:mid]) == false {        mid++ // add another byte from myString until we have a whole multi-byte character    }    if len(myString) > mid {        myString = myString[:mid]    }    fmt.Println(myString) // Prints the first 100 bytes, or the whole string if shorter}或者,如果您可以接受从输出中删除最多一个字符,则此版本会更简洁一些func main() {    myString := "日本語"    for len(myString) >= maxLen || utf8.ValidString(myString) == false {        myString = myString[:len(myString)-1] // remove a byte    }    fmt.Println(myString) // Prints the first 100 bytes, or the whole string if shorter}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go