不可變的字串值和指標位址
在Go 中,官方規範規定字串是不可變的,這意味著它們的內容一旦創建就無法更改。然而,以下程式碼片段出現了一個奇怪的現象:
str := "hello" fmt.Printf("%p\n",&str) // 0x1040c128 fmt.Printf("%v\n",str) // hello ptr := &str *ptr = "world" fmt.Printf("%p\n",&str) // 0x1040c128 fmt.Printf("%v\n",str) // world
與預期相反,將「world」分配給取消引用的指標 *ptr 後,&str 的位址保持不變。
這種現象需要理解在這種情況下「不變性」的意思。 Go 中的字串值是不可變的,而不是保存它們的變數。在程式碼範例中,str是字串類型的變量,其值可以更改。
字串值「hello」本身是不可變的。將“world”指派給 str 不會改變“hello”,而只是將 str 變數的值改為“world”。此變更與值的設定方式無關,無論是直接設定還是透過指標設定。
不可變的字串值可確保共用字串在整個程式中保持一致。例如,如果函數接收字串參數,則無法在該函數內變更其值。因此,相同字串值的後續列印語句將始終產生預期結果。
在內部,字串值由reflect.StringHeader結構表示。這些結構儲存指向文字的 UTF-8 編碼值及其位元組長度的指標。該數據不可訪問,無法直接修改。此外,字串值不能被索引和指派新值。
雖然 Go 規範保證字串值的不變性,但使用 unsafe 套件可以覆寫這些保證。然而,這樣做會放棄語言規範所提供的保護和安全性。
以上是為什麼在 Go 中透過指標更改字串的值不會更改其記憶體位址?的詳細內容。更多資訊請關注PHP中文網其他相關文章!