1

在 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比较字符串的值。

有什么方法可以测试字符串本身是否存储在同一个地方(即strC-struct中的字段具有相同的值),这样比较aandb最有可能 yield false,而比较candd几乎肯定会 yield true

4

2 回答 2

5

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

注意:StringHeader结构是一个实现细节,语言规范中没有提到。因此,任何像上面段落中讨论的那样做事情的代码都不是真正可移植的 Go。IOW,我不鼓励在好奇心/研究等之外使用此类代码。来自文档:

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

编辑:

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

hdr := (*reflect.StringHeader)(unsafe.Pointer(&str))
于 2013-07-26T19:12:02.693 回答
-1

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

于 2013-07-26T20:50:06.520 回答