您现在的位置是:群英 > 开发技术 > 编程语言
Go String是什么?有些什么功能呢?
Admin发表于 2022-06-28 17:16:14590 次浏览
这篇文章主要为大家详细介绍了Go String是什么?有些什么功能呢?,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望对大家学习或工作能有帮助。



什么是字符串?

在 Go 中,字符串是一个 (可能为空) 不可变的字节序列。对于我们来说,这里的关键词是 不可变。因为字节片是可变的,所以在 string 和 []byte 之间进行转换通常需要分配和复制,这是很昂贵的。

在幕后,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 issue 29696。)


以上就是关于“Go String是什么?有些什么功能呢?”的介绍了,感谢各位的阅读,希望文本对大家有所帮助。如果想要了解更多知识,欢迎关注群英网络,小编每天都会为大家更新不同的知识。

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

标签: Golang
相关信息推荐
2022-07-06 17:12:18 
摘要:这篇文章主要为大家介绍了golang开发安装go-torch火焰图操作步骤
2022-05-14 14:59:36 
摘要:html5的doctype声明是“<!DOCTYPE HTML>”,它是一条指令,用于告知浏览器文档所使用的是HTML规范。doctype声明必须位于HTML5文档中的第一行,也就是位于“<html>”标签之前。
2022-07-11 17:49:23 
摘要:去除步骤:1、使用foreach语句采用引用方式循环遍历数组,语法“foreach ($arr as &$v){循环体语句块;}”;2、在循环体中,使用is_string()函数判断数组元素“$v”是否为字符串类型,如果是则使用settype()函数将该元素设置为其他类型即可,语法“if(is_string($v)){settype($v,"指定类型");}”。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部