Go の値セマンティクスとポインタ セマンティクスを理解する
Go では、値セマンティクスとポインタ セマンティクスの概念を理解することが、内部構造を理解するために重要です。配列の仕組みとスライス。
値のセマンティクス
Go で値が関数またはメソッドに渡されると、それらの値のコピーが作成されます。これらのコピーは元の値から分離されています。つまり、関数またはメソッド内で行われた変更は元の値に影響しません。
たとえば、次のコードを考えてみましょう。
func double(i int) int { i *= 2 return i } func main() { i := 1 fmt.Println("double:", double(i)) fmt.Println("original i:", i) }
出力このコードの値のセマンティクスは次のとおりです。
double: 2 original i: 1
double() が i パラメーターを変更しても、呼び出し側関数の i 変数は変更されません。これは、i のコピーが double() に渡されたためです。
ポインター セマンティクス
値セマンティクスとは異なり、ポインター セマンティクスは、値へのポインターが次の場合を指します。値自体の代わりに渡されます。関数またはメソッド内でポインターが変更されると、その変更は元の値に反映されます。
次のコードを考えてみましょう:
func doublep(i *int) int { *i *= 2 return *i } func main() { i := 1 fmt.Println("double:", doublep(&i)) fmt.Println("original i:", i) }
このコードの出力は、ポインターのセマンティクスを示しています。
double: 2 original i: 2
この例では、i へのポインターが doublep() に渡され、関数が i の元の値を変更できるようになります。
スライスの受け渡し: 値セマンティクスの例外
Go は値セマンティクスに従いますが、配列とスライスはポインタ セマンティクスを示します。スライスが関数またはメソッドに渡されると、(基礎となる配列ではなく) スライス ヘッダーのコピーが作成されます。ただし、元のスライスとコピーされたスライスは両方とも、同じ基礎となる配列を参照します。したがって、関数またはメソッド内のスライスの要素への変更は、元のスライスに反映されます。
この動作は、次のコードで明らかです。
func doubles(is []int) []int { for i := range is { is[i] *= 2 } return is } func main() { is := []int{1, 2} fmt.Println("double:", doubles(is)) fmt.Println("original is:", is) }
出力:
double: [2 4] original is: [2 4]
Go でデータを効果的に操作するには、値とポインターのセマンティクスを理解することが不可欠です。これにより、開発者は値を操作するときに関数やメソッドの動作を予測できます。
以上がGo では値とポインターのセマンティクスはどのように異なりますか?また、スライスはどのように例外的な動作を示しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。