> 백엔드 개발 > Golang > Go에서 변수를 공유하면 익명 함수 내 범위에 따라 다른 결과가 나오는 이유는 무엇입니까?

Go에서 변수를 공유하면 익명 함수 내 범위에 따라 다른 결과가 나오는 이유는 무엇입니까?

Barbara Streisand
풀어 주다: 2024-11-07 02:40:02
원래의
650명이 탐색했습니다.

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

Go에서 변수 공유: 두 경우의 차이점 이해

Go에서 고루틴은 메모리를 공유하고 통신할 수 있는 경량 동시 작업입니다. 채널. 고루틴 간의 변수 공유에는 데이터 경합 문제를 피하기 위해 신중한 처리가 필요합니다.

다음 Go 프로그램을 고려하세요.

<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>
로그인 후 복사

이 프로그램이 실행되면 예상되는 출력이 인쇄됩니다.

4
0
1
3
2
로그인 후 복사

이 경우 각 고루틴에는 고루틴이 생성될 때 현재 i 값으로 초기화되는 변수 x의 자체 복사본이 있습니다. 이는 x가 익명 함수 내에서 선언되고 범위가 해당 함수로 제한되기 때문입니다.

이제 프로그램을 약간 수정해 보겠습니다.

<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>
로그인 후 복사

이번에는 출력 됩니다:

5
5
5
5
5
로그인 후 복사

설명은 고루틴에서 변수 i가 사용되는 방식에 있습니다. i는 익명 함수 외부에 선언되므로 모든 고루틴에서 공유됩니다. 이 경우 각 고루틴이 fmt.Println(i)을 실행할 때 i의 최종 값인 5를 인쇄합니다.

이를 확인하기 위해 x 및 i의 메모리 주소 인쇄를 추가할 수 있습니다. 고루틴. 출력은 x가 각 고루틴에 대해 서로 다른 주소를 갖는 반면 i는 모든 고루틴에 대해 동일한 주소를 가지고 있음을 보여줍니다.

0xc0420301e0
0xc0420301f8
0xc0420301e8
0xc0420301f0
0xc042030200
0xc042030208
로그인 후 복사

결론적으로 두 경우 간의 변수 공유 차이는 변수의 범위에서 발생합니다. 익명 함수에 선언되었습니다. 익명 함수 내에서 변수가 선언되면 해당 고루틴에만 적용됩니다. 반면 익명 함수 외부에 선언된 변수는 모든 고루틴에서 공유됩니다.

위 내용은 Go에서 변수를 공유하면 익명 함수 내 범위에 따라 다른 결과가 나오는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿