为了账号安全,请及时绑定邮箱和手机立即绑定

有没有办法判断两个字符串是否在 Go 中共享内存?

有没有办法判断两个字符串是否在 Go 中共享内存?

Go
富国沪深 2021-06-10 16:09:30
在 Go 中,字符串在内部存储为 C 结构:struct String // This is C code (not Go){  byte* str;  int32 len;};假设我有以下变量:a0 := "ap" // This is Go codea1 := "ple"b0 := "app"b1 := "le"a := a0 + a1b := b0 + b1c := "apple"d := c然后如下代码:fmt.Println("a == b = %t, &a == &b = %t", a == b, &a == &b)fmt.Println("c == d = %t, &c == &d = %t", c == d, &c == &d)输出:a == b = true, &a == &b = falsec == d = true, &c == &d = false因为&a == &b比较 C 结构的地址,而a == b比较字符串的值。有没有办法测试字符串本身是否存储在同一个地方(即strC 结构中的字段具有相同的值),这样比较a和b很可能会产生false,而比较c和d几乎肯定会产生true?
查看完整描述

2 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

是的,这是可能的。使用reflect包获取两个实例的String Headersstring。然后,你可以比较两个DataLen领域来计算字符串数组的支持是否在内存中确实重叠。

注意:StringHeaderstruct 是一个实现细节,语言规范中没有提到它。因此,任何执行上一段中讨论的操作的代码都不是真正可移植的 Go。IOW,我不鼓励在好奇心/研究等之外使用此类代码。来自文档:

StringHeader 是字符串的运行时表示。它不能安全或可移植地使用,其表示形式可能会在以后的版本中更改。此外,Data 字段不足以保证它引用的数据不会被垃圾收集,因此程序必须保留一个单独的、正确类型的指向底层数据的指针。

编辑:

*reflect.StringHeader hdrstring实例获取 a 的未经测试的代码str

hdr := (*reflect.StringHeader)(unsafe.Pointer(&str))


查看完整回答
反对 回复 2021-06-21
?
慕哥6287543

TA贡献1831条经验 获得超10个赞

strings的程度是 Go 编译器实现的细节。对于当前gcgccgo编译器,相同的string文字在编译和链接时被保留。在运行时生成的其他string文字和strings 不会被实习。


查看完整回答
反对 回复 2021-06-21
  • 2 回答
  • 0 关注
  • 226 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信