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

时间:2013-07-26 18:13:59

标签: string go equality

在Go中,字符串在内部存储为C-struct:

struct String // This is C code (not Go)
{
  byte* str;
  int32 len;
};

假设我有以下变量:

a0 := "ap" // This is Go code
a1 := "ple"
b0 := "app"
b1 := "le"
a := a0 + a1
b := b0 + b1
c := "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 = false
c == d = true, &c == &d = false

因为&a == &b比较了C结构的地址,而a == b比较了字符串的值。

有没有办法测试字符串本身是否存储在同一个地方(即C-struct中的str字段具有相同的值),以便比较a和{{ 1}}最有可能产生b,而比较falsec几乎肯定会产生d

2 个答案:

答案 0 :(得分:5)

是的,这是可能的。使用反射包并获取两个string实例的String Headers。然后,您可以比较两个 DataLen字段,以计算字符串支持数组是否在内存中重叠。

注意:StringHeader结构是一个实现细节,语言规范没有提到它。因此,任何代码执行上面讨论的内容都不是真正的便携式Go。 IOW,我不鼓励在好奇心/研究等之外使用这些代码。来自文档:

  

StringHeader是字符串的运行时表示。它不能安全或便携地使用,其表示可能会在以后的版本中更改。此外,数据字段不足以保证它引用的数据不会被垃圾收集,因此程序必须保留一个单独的,正确键入的指向基础数据的指针。

编辑:

*reflect.StringHeader实例hdr获取string str的未经测试的代码:

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

答案 1 :(得分:-1)

string被实现的程度是Go编译器实现细节。对于当前的gcgccgo编译器,在编译和链接时都会使用相同的string文字。 string文字和string不会被实习。