文字列は不変であるにもかかわらず、Go で文字列変数へのアクセスを同期する必要があるのはなぜですか?

DDD
リリース: 2024-11-03 06:52:02
オリジナル
252 人が閲覧しました

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

文字列の不変性とスレッド同期

Go の文字列は不変ですが、その参照を保持する変数は不変ではありません。したがって、マルチスレッド環境で文字列を操作する場合は、文字列自体ではなく文字列変数へのアクセスを同期する必要があります。

文字列がアトミックに型付けされない理由

アトミック型は、初期化後にその値が決して変更されないことを保証します。ただし、文字列変数は再割り当てできるため、文字列はアトミックに型付けされません。

文字列変数の同期

複数のスレッドが文字列変数にアクセスする場合は常に同期が必要です。少なくとも 1 回のアクセスは書き込みです。これは、文字列の値は、文字列自体を変更することではなく、変数を再割り当てすることによってのみ変更できるためです。

実際

文字列値「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 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!