根据golang中的字节长度分割字符串

Joy*_*Lee 1 http go http-headers

http请求标头的长度限制为4k。我想基于此限制拆分要包含在标题中的字符串。我应该[]byte(str)先分割后再使用string([]byte)每个分割部分转换回字符串吗?有没有更简单的方法可以做到这一点?

Jas*_*son 5

在Go中,字符串实际上只是字节序列,对字符串进行索引会生成bytes。因此,您可以通过将字符串切成4kB子字符串来简单地将其拆分为子字符串。

但是,由于UTF-8字符可以跨越多个字节,因此您有可能在一个字符序列的中间进行拆分。如果拆分后的字符串在解码之前总是在另一端以相同顺序再次连接在一起,那么这不是问题,但是,如果尝试分别解码每个字符串,则可能会导致无效的前导或尾随字节序列。如果要防止这种情况,可以使用该unicode/utf8软件包检查是否在有效的前导字节上拆分,如下所示:

package httputil

import "unicode/utf8"

const maxLen = 4096

func SplitHeader(longString string) []string {
    splits := []string{}

    var l, r int
    for l, r = 0, maxLen; r < len(longString); l, r = r, r+maxLen {
        for !utf8.RuneStart(longString[r]) {
            r--
        }
        splits = append(splits, longString[l:r])
    }
    splits = append(splits, longString[l:])
    return splits
}
Run Code Online (Sandbox Code Playgroud)

直接切片字符串比转换[]byte来回更有效,因为既然a string是不可变的,而a []byte不是不可改变的,则转换时必须将数据复制到新的内存中,这需要O(n)时间(双向!),而切片a string仅返回一个新的字符串标头,该标头由与原始数组相同的数组支持(采用固定时间)。