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()는 슬라이스를 수신하고 초기 값을 인쇄합니다. 그런 다음 다른 고루틴이 슬라이스를 수정할 때까지 기다린 다음 수정된 값을 인쇄합니다. 이는 슬라이스 값이 동시에 변경될 수 있음을 보여줍니다. 그러나 SliceTest()가 문자열 인수를 수신하는 경우 이러한 수정은 발생하지 않습니다.
위 내용은 문자열이 불변임에도 불구하고 Go에서 문자열 변수에 대한 액세스를 동기화해야 하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!