> 백엔드 개발 > Golang > Go의 'for range' 루프가 함수 리터럴과 다른 동작을 보이는 이유는 무엇입니까?

Go의 'for range' 루프가 함수 리터럴과 다른 동작을 보이는 이유는 무엇입니까?

Susan Sarandon
풀어 주다: 2024-12-10 20:52:11
원래의
470명이 탐색했습니다.

Why Does Go's `for range` Loop Exhibit Different Behavior with Function Literals?

Go의 다양한 루프 동작 이해

Go에서 루프를 구성할 때 for range 루프의 동작을 이해하는 것이 중요합니다. 뚜렷한 동작을 보이는 다음 두 가지 루프 변형을 고려하십시오.

루프 변형 1:

func loop1() {

    actions := make(map[string]func())

    for _, cmd := range cmds {
        actions[cmd] = func() {
            fmt.Println(cmd)
        }
    }
    for _, action := range actions {
        action()
    }
}
로그인 후 복사

루프 변형 2:

func loop2() {

    actions := make(map[string]func())

    for i, cmd := range cmds {
        command := cmds[i]
        actions[cmd] = func() {
            fmt.Println(command)
        }
    }
    for _, action := range actions {
        action()
    }
}
로그인 후 복사

출력 관찰:

  • Loop1은 "update"(3회 반복) 출력을 생성합니다.
  • Loop2는 "delete", "update", "create"
  • 출력을 생성합니다.

루프 변형의 근본적인 문제 1:

문제는 func loop1() 루프에 있습니다. 각 루프 반복은 액션 맵에 함수 리터럴을 할당합니다. 이 함수 리터럴은 루프 변수 cmd를 참조합니다. 그러나 cmd 인스턴스는 하나만 있으며 루프가 끝나면 명령 슬라이스의 마지막 값인 "update"가 유지됩니다. 이는 포함된 모든 함수가 동일한 루프 변수(cmd)를 참조하여 모든 함수가 호출될 때 "update"를 인쇄한다는 것을 의미합니다.

해결책:

이 문제를 해결하려면 , 각 루프 반복 내에서 루프 변수의 복사본을 만들어 각 함수 리터럴이 자체 독립적인 copy:

func loop1() {
    actions := make(map[string]func())

    for _, cmd := range cmds {
        cmd2 := cmd
        actions[cmd] = func() {
            fmt.Println(cmd2) // Refer to the detached, copy variable!
        }
    }
    for _, action := range actions {
        action()
    }
}
로그인 후 복사

결론:

결론적으로 for range 루프를 사용할 때 루프 변수의 범위와 참조를 고려하는 것이 중요합니다. 필요할 때 루프 변수의 복사본이 만들어지도록 하면 특히 해당 변수를 참조하는 함수 리터럴을 처리할 때 올바른 동작이 보장됩니다.

위 내용은 Go의 'for range' 루프가 함수 리터럴과 다른 동작을 보이는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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