Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah perkongsian pembolehubah dalam Go membawa kepada output yang berbeza bergantung pada skopnya dalam fungsi tanpa nama?

Mengapakah perkongsian pembolehubah dalam Go membawa kepada output yang berbeza bergantung pada skopnya dalam fungsi tanpa nama?

Barbara Streisand
Barbara Streisandasal
2024-11-07 02:40:02550semak imbas

Why does sharing variables in Go lead to different outputs depending on their scope within anonymous functions?

Berkongsi Pembolehubah dalam Go: Memahami Perbezaan Antara Dua Kes

Dalam Go, goroutine ialah tugas serentak ringan yang boleh berkongsi memori dan berkomunikasi menggunakan saluran. Perkongsian pembolehubah antara gorouti memerlukan pengendalian yang teliti untuk mengelakkan isu perlumbaan data.

Pertimbangkan program Go berikut:

<code class="go">package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)

        x := i

        go func() {
            defer wg.Done()
            fmt.Println(x)
        }()

    }

    wg.Wait()
    fmt.Println("Done")
}</code>

Apabila dilaksanakan, program ini mencetak output yang dijangkakan:

4
0
1
3
2

Dalam kes ini, setiap goroutine mempunyai salinan sendiri pembolehubah x, yang dimulakan dengan nilai semasa i apabila goroutine dicipta. Ini kerana x diisytiharkan dalam fungsi tanpa nama dan skopnya terhad kepada fungsi itu.

Sekarang, pertimbangkan sedikit pengubahsuaian pada program:

<code class="go">package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)

        go func() {
            defer wg.Done()
            fmt.Println(i)
        }()

    }

    wg.Wait()
    fmt.Println("Done")
}</code>

Kali ini, output menjadi:

5
5
5
5
5

Penjelasan terletak pada cara pembolehubah i digunakan dalam goroutine. Memandangkan i diisytiharkan di luar fungsi tanpa nama, ia dikongsi antara semua goroutine. Dalam kes ini, apabila setiap goroutine melaksanakan fmt.Println(i), ia mencetak nilai akhir i, iaitu 5.

Untuk mengesahkan ini, kita boleh menambah pencetakan alamat memori x dan i dalam goroutine. Output menunjukkan bahawa x mempunyai alamat yang berbeza untuk setiap goroutine, manakala i mempunyai alamat yang sama untuk semua goroutine:

0xc0420301e0
0xc0420301f8
0xc0420301e8
0xc0420301f0
0xc042030200
0xc042030208

Kesimpulannya, perbezaan perkongsian pembolehubah antara kedua-dua kes timbul daripada skop pembolehubah diisytiharkan dalam fungsi tanpa nama. Apabila pembolehubah diisytiharkan dalam fungsi tanpa nama, ia adalah peribadi kepada goroutine itu. Sebaliknya, pembolehubah yang diisytiharkan di luar fungsi tanpa nama dikongsi antara semua goroutine.

Atas ialah kandungan terperinci Mengapakah perkongsian pembolehubah dalam Go membawa kepada output yang berbeza bergantung pada skopnya dalam fungsi tanpa nama?. 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