189 8069 5689

go语言中的String是什么-创新互联

字符串概念

十载的靖远网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都营销网站建设的优势是能够根据用户设备显示端的尺寸不同,自动调整靖远建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联建站从事“靖远网站设计”,“靖远网站推广”以来,每个客户项目都认真落实执行。

字符串是不可变字节(byte)序列,其本身是一个复杂的结构。默认以UTF-8编码存储Unicode字符,内置函数len()返回字节数组长度。字符串默认值不是nil,而是""。

在幕后,Go 的字符串 (当前) 表示为 长度和指向字符串数据的指针.

字符串驻留

考虑这段代码:

b := []byte("hello")
s := string(b)
t := string(b)

s 和 t 是字符串,因此它们都有长度和数据指针。它们的长度显然是相同的。那它们的数据指针呢?

Go 语言无法为我们提供直接的查找方法。但是我们可以使用 unsafe 来探查:

func pointer(s string) uintptr {
    p := unsafe.Pointer(&s)
    h := *(*reflect.StringHeader)(p)
    return h.Data
}

(此函数应返回 unsafe.Pointer。详见 Go 问题 19367。)

如果我们 fmt.Println(pointer(s), pointer(t)),我们会得到类似 4302664 4302632 的信息。指针是不同的;它们有两个单独的数据副本 hello。

(这是一个练习链接。如果你想要尝试,将 "hello" 变成 "h" 会发生什么情况?解释  )

假设您希望重新使用数据 hello 的单个副本?这就是字符串驻留。字符串驻留有两个优点。明显的一个优点是,你不需要分配和复制数据。另一个优点是它加快了字符串相等性检查的速度。如果两个字符串具有相同的长度和相同的数据指针,则它们是相等的;没有必要检查字节。

从 Go 1.14 开始,Go 不会驻留大多数字符串。与其它形式的缓存一样,驻留也有成本:并发安全性的同步,垃圾收集器的复杂性,以及每次创建字符串时要执行的额外代码。而且,就像缓存一样,在某些情况下它是有害的,而不是有用的。如果你在处理字典里的单词,则任何单词都不会出现两次,这时,字符串驻留既浪费时间又浪费内存。

手动字符串驻留

可以在 Go 中手动驻留字符串。我们需要的是一种在给定字节切片 (byte slice) 的情况下寻找现有字符串以重新使用的方法,也许使用诸如 map[[]byte]string 之类的方法。如果查找成功,则使用现有字符串;如果失败,我们将转换并存储该字符串以备将来使用。

这里只有一个问题:您不能使用 []byte 作为 map 的键。

多亏了长期的编译器优化,我们可以使用 map[string]string 代替。这里有一个优化,键是转换后字节切片的 map 操作实际上不会生成在查找期间会用到的新字符串。

m := make(map[string]string)
b := []byte("hello")
s := string(b) // 分配了
_ = m[string(b)] // 不分配!

(类似的优化适用于其他情况,在这些情况下,编译器可以证明转换后的字节切片在使用过程中不会被修改,例如 switch string(b),当所有 switch 情况都没有副作用时。)

驻留字符串所需的全部代码是这样的:

func intern(m map[string]string, b []byte) string {
    // 查找一个存在的字符串来重用
    c, ok := m[string(b)]
    if ok {
        // 找到一个存在的字符串
        return c
    }
    // 没有找到,所以制作一个并且存储它
    s := string(b)
    m[s] = s
    return s
}

很简单

新出现的困难(并发症)

请注意,这个手动驻留例程将驻留问题推入了调用代码。您需要管理对 map 的并发访问;您需要确定 map (以及其中的所有内容) 的生命周期;并且您每次需要字符串时都需要付出 map 查找的额外费用。

将这些决定推到调用代码上可以产生更好的性能。例如,假设您正在将 json 解码为 map[string]interface{}。json 解码器可能不是并发的。map 的生命周期可以绑定到 json 解码器。并且此 map 的键很可能会经常重复,这是字符串驻留的最佳情况;这使得额外的 map 查找成本值得。

一个助手包

如果您不想考虑这些并发症中的任何一个,并且愿意接受轻微的性能损失,并且有字符串驻留可能会有所帮助的代码,则有一个为此的包:github.com/josharian/intern。

它的工作原理是可怕的滥用 sync.Pool。它将驻留 maps 存储在 sync.Pool 中,根据需要检索它们。这很好的解决了并发访问问题,因为 sync.Pool 的访问是并发安全的。它主要解决了生存期问题,因为在 sync.Pool 中的内容通常最终会被垃圾收集。

以上就是Go String 解析的详细内容,更多请关注创新互联成都网站设计公司其它相关文章!

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前标题:go语言中的String是什么-创新互联
分享网址:http://cdxtjz.cn/article/dsiphe.html

其他资讯