Http 基于golang中的字节长度拆分字符串

Http 基于golang中的字节长度拆分字符串,http,go,http-headers,Http,Go,Http Headers,http请求头的长度限制为4k。 我想根据此限制拆分要包含在标题中的字符串。 我是否应该先使用[]字节(str)进行拆分,然后再使用字符串([]字节)将每个拆分部分转换回字符串? 有更简单的方法吗?在Go中,字符串实际上只是一个字节序列,并且。因此,您可以简单地将字符串分割成4kB的子字符串 但是>,因为UTF-8字符可以跨越多个字节,所以有可能在字符序列中间分裂。如果在解码之前分割的字符串在另一端总是以相同的顺序再次连接在一起,则这不是问题,但是如果尝试单独解码每个字符串,则可能会导致无效的

http请求头的长度限制为4k。 我想根据此限制拆分要包含在标题中的字符串。 我是否应该先使用
[]字节(str)
进行拆分,然后再使用
字符串([]字节)
将每个拆分部分转换回字符串?
有更简单的方法吗?

在Go中,字符串实际上只是一个字节序列,并且。因此,您可以简单地将字符串分割成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
}
包httputil
导入“unicode/utf8”
常数maxLen=4096
func SplitHeader(长字符串)[]字符串{
拆分:=[]字符串{}
变量l,r int
对于l,r=0,maxLen;r

直接切片字符串比转换为
[]字节
再转换回来更有效,因为
字符串
是不可变的,而
[]字节
不是,因此转换时必须将数据复制到新内存中,这需要O(n)个时间(两种方式!),而切片一个字符串只会返回一个新的字符串头,该头由与原始字符串相同的数组支持(需要固定的时间)

在Go中,字符串实际上只是一个字节序列,并且。因此,您可以简单地将字符串分割成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
}
包httputil
导入“unicode/utf8”
常数maxLen=4096
func SplitHeader(长字符串)[]字符串{
拆分:=[]字符串{}
变量l,r int
对于l,r=0,maxLen;r

直接切片字符串比转换为
[]字节
再转换回来更有效,因为
字符串
是不可变的,而
[]字节
不是,因此转换时必须将数据复制到新内存中,这需要O(n)个时间(两种方式!),而切片一个字符串只会返回一个新的字符串头,该头由与原始字符串相同的数组支持(需要固定的时间)

我写了一个基准测试来证明你是错的,但我被证明是错的,字符串切片操作比字节切片操作快近5000ns/op。现在我很好奇为什么它更快!我假设切片一个
字符串
和切片一个
[]字节
所需的时间大致相同,因为在这两种情况下,您都只是在构造一个引用现有底层数组的新切片头。它在两者之间转换应该是低效的,因为它必须复制整个范围。您是否在基准测试中包含了转换?结果表明
字符串
头与普通切片头略有不同;它不包括
cap
字段,因为您无法通过重新选择
字符串使其超出其长度。因此,计算一个新的
字符串
头实际上比计算一个新的切片头更有效!请参阅Go源代码中的。以下是程序。这是我的答案。是的,切片头和字符串头不同,可能也是因为其他额外的容量检查,因为它可以为不同的切片设置不同。我写了一个基准来证明你错了,但我被证明是错的,字符串切片操作比字节切片操作快近5000ns/op。现在我很好奇为什么它更快!我假设切片一个
字符串
和切片一个
[]字节
所需的时间大致相同,因为在这两种情况下,您都只是在构造一个引用现有底层数组的新切片头。它在两者之间转换应该是低效的,因为它必须复制整个范围。您是否在基准测试中包含了转换?结果表明
字符串
头与普通切片头略有不同;它不包括
cap
字段,因为您无法通过重新选择
字符串使其超出其长度。因此,计算一个新的
字符串
头实际上比计算一个新的切片头更有效!请参阅Go源代码中的。以下是程序。这是我的答案。是的,切片头和字符串头不同,可能这也是因为其他额外的容量检查,因为它可以为不同的切片设置不同。