雖然 Go 中的字串是不可變的,但保存其引用的變數卻不是。因此,在多執行緒環境中處理字串時,有必要同步對字串變數的訪問,而不是字串本身。
為什麼字串不是原子類型的
原子型保證其值在初始化後永遠不會被修改。但是,由於字串變數可以重新賦值,因此字串不是原子類型的。
字串變數的同步
每當多個執行緒存取字串變數時都需要同步,其中至少一次存取是寫入。這是因為字串的值只能透過重新分配變數來更改,而不能透過修改字串本身來更改。
實踐
如果你有一個字串值“hello ”,假設您沒有為變數分配新值,它將無限期地保持“hello”。但是,如果您有一個切片值 []byte{1, 2, 3},則即使該切片是按值傳遞的,也可以同時修改其元素。
請考慮以下範例:
var sig = make(chan int) func main() { s := []byte{1, 2, 3} go func() { <-sig s[0] = 100 sig <- 0 }() sliceTest(s) } func sliceTest(s []byte) { fmt.Println("First s =", s) sig <- 0 // send signal to modify now <-sig // Wait for modification to complete fmt.Println("Second s =", s) }
輸出:
First s = [1 2 3] Second s = [100 2 3]
在此範例中,sliceTest() 接收一個切片並列印其初始值。然後它等待另一個 goroutine 修改切片,然後列印其修改後的值。這表示切片值可以同時變更。但是,如果 sliceTest() 接收字串參數,則不會發生此修改。
以上是儘管字串是不可變的,為什麼我需要同步 Go 中對字串變數的存取?的詳細內容。更多資訊請關注PHP中文網其他相關文章!