ホームページ >バックエンド開発 >Golang >Go でポインタを介して文字列の値を変更してもメモリ アドレスが変更されないのはなぜですか?

Go でポインタを介して文字列の値を変更してもメモリ アドレスが変更されないのはなぜですか?

DDD
DDDオリジナル
2024-12-13 07:33:10986ブラウズ

Why Does Changing a String's Value via a Pointer in Go Not Change Its Memory Address?

不変の文字列値とポインタ アドレス

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」に変更されるだけです。この変更は、値の設定方法 (直接かポインタ経由か) には依存しません。

不変の文字列値により、プログラム全体で共有文字列の一貫性が保たれます。たとえば、関数が文字列引数を受け取った場合、その関数内でその値を変更することはできません。したがって、同じ文字列値の後続の print ステートメントは、常に予期した結果を生成します。

内部的に、文字列値は、reflect.StringHeader 構造体によって表されます。これらの構造体には、UTF-8 でエンコードされたテキストの値とそのバイト長へのポインターが格納されます。このデータにはアクセスできないため、直接変更できません。さらに、文字列値にインデックスを付けたり、新しい値を割り当てたりすることはできません。

Go 仕様では文字列値の不変性が保証されていますが、unsafe パッケージを使用するとこれらの保証が無効になる可能性があります。ただし、これを行うと、言語仕様によって提供される保護と安全性が放棄されます。

以上がGo でポインタを介して文字列の値を変更してもメモリ アドレスが変更されないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。