Rumah >pembangunan bahagian belakang >Golang >Mengapa Saya Perlu Menyegerakkan Akses kepada Pembolehubah Rentetan dalam Go, Walaupun Rentetan Tidak Boleh Berubah?

Mengapa Saya Perlu Menyegerakkan Akses kepada Pembolehubah Rentetan dalam Go, Walaupun Rentetan Tidak Boleh Berubah?

DDD
DDDasal
2024-11-03 06:52:02320semak imbas

Why Do I Need to Synchronize Access to String Variables in Go, Even Though Strings Are Immutable?

Ketidakbolehubahan Rentetan dan Penyegerakan Benang

Walaupun rentetan dalam Go tidak berubah, pembolehubah yang memegang rujukannya tidak. Oleh itu, apabila bekerja dengan rentetan dalam persekitaran berbilang benang, adalah perlu untuk menyegerakkan akses kepada pembolehubah rentetan, bukan rentetan itu sendiri.

Mengapa Rentetan Tidak Ditaip Secara Atom

Jenis atom menjamin bahawa nilainya tidak pernah diubah suai selepas permulaan. Walau bagaimanapun, memandangkan pembolehubah rentetan boleh ditugaskan semula, rentetan tidak ditaip secara atom.

Penyegerakan untuk Pembolehubah Rentetan

Penyegerakan diperlukan apabila berbilang benang mengakses pembolehubah rentetan, di mana pada sekurang-kurangnya satu akses ialah tulis. Ini kerana nilai rentetan hanya boleh ditukar dengan menetapkan semula pembolehubah, bukan dengan mengubah suai rentetan itu sendiri.

Dalam Amalan

Jika anda mempunyai nilai rentetan "hello ", ia akan kekal "hello" selama-lamanya, dengan mengandaikan anda tidak memberikan nilai baharu kepada pembolehubah. Walau bagaimanapun, jika anda mempunyai nilai hirisan []bait{1, 2, 3}, elemennya boleh diubah suai secara serentak, walaupun jika hirisan itu diluluskan oleh nilai.

Pertimbangkan contoh berikut:

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)
}

Output:

First  s = [1 2 3]
Second s = [100 2 3]

Dalam contoh ini, sliceTest() menerima kepingan dan mencetak nilai awalnya. Ia kemudian menunggu goroutine lain untuk mengubah suai kepingan dan kemudian mencetak nilai diubah suainya. Ini menunjukkan bahawa nilai hirisan boleh diubah secara serentak. Walau bagaimanapun, jika sliceTest() menerima hujah rentetan, pengubahsuaian ini tidak akan berlaku.

Atas ialah kandungan terperinci Mengapa Saya Perlu Menyegerakkan Akses kepada Pembolehubah Rentetan dalam Go, Walaupun Rentetan Tidak Boleh Berubah?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn