2013-07-26 17 views
1

在圍棋中,字符串在內部存儲爲C-結構:有沒有什麼辦法可以判斷兩個字符串在Go中共享內存?

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-結構的str領域具有相同的值)的字符串,這樣比較a,並會b最有可能的產量false,而比較cd幾乎肯定會產生true

回答

5

是的,這是可能的。使用反射包並獲得兩個string實例的String Headers。然後,您可以比較DataLen字段,以計算字符串背景數組是否在內存中重疊。

注意:StringHeader結構是一個實現細節,它沒有被語言規範提及。因此,上面討論過的任何代碼都不是可移植的Go。 IOW,我不希望在好奇/研究之外使用此類代碼。從文檔:

StringHeader是字符串的運行時表示形式。它不能被安全或便攜地使用,並且其表示可能在以後的版本中發生變化。此外,數據字段不足以保證它所引用的數據不會被垃圾收集,因此程序必須保持一個單獨的,正確類型的指向底層數據的指針。

編輯:

未經測試的代碼從string實例str得到*reflect.StringHeaderhdr

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

謝謝!你可以通過將'string'投入到'StringHeader'來使用它嗎? – Matt

+0

@Matt:在Go中沒有__鑄造。請參閱最新的答案。 – zzzz

+0

我仍然會打電話給那個演員。但是,謝謝! – Matt

-1

string s的拘禁度是一個圍棋編譯器實現的細節。對於當前gcgccgo編譯器,相同的string文字在編譯和鏈接時被執行。在運行時生成的其他string文字和string未被攔截。

+0

這不是我的問題。 – Matt

+0

爲了正確解釋「str」相等測試的結果,瞭解這些重要信息。 – peterSO

+0

如果我期望字符串被攔截,那麼爲什麼我需要檢查它們是否共享內存? – Matt

相關問題