수색…
폐쇄 기본 사항
Closure 는 환경과 함께 취해지는 기능입니다. 이 함수는 일반적으로 다른 함수 내에서 정의 된 익명 함수입니다. 환경은 둘러싼 함수의 어휘 범위입니다 (함수의 어휘 범위에 대한 기본적인 개념은 함수의 중괄호 사이에 존재하는 범위입니다).
func g() {
i := 0
f := func() { // anonymous function
fmt.Println("f called")
}
}
다른 함수 (예 : g
) 내에 정의 된 익명의 함수 (예 : f
)의 본문 내에서 f
와 g
범위에있는 변수에 액세스 할 수 있습니다. 그러나 g
의 범위는 클로저의 환경 부분을 형성하고 (함수 부분은 f
) 결과적으로 g
의 범위에있는 변수에 대한 변경 사항은 해당 값을 유지합니다 (즉, 환경은 f
를 호출하는 사이에 지속됩니다) .
아래 함수를 고려하십시오.
func NaturalNumbers() func() int {
i := 0
f:= func() int { // f is the function part of closure
i++
return i
}
return f
}
위의 정의에서, NaturalNumbers
내부 기능 갖는다 f
NaturalNumbers
복귀. 내부 f
, NaturalNumbers
의 범위 내에서 정의 된 변수 i
에 액세스 중입니다.
NaturalNumbers
과 같이 새로운 함수를 얻습니다.
n := NaturalNumbers()
이제 n
은 종결 자입니다. 연관된 환경 ( NaturalNumbers
)도 가지고있는 함수 ( f
정의)입니다.
n
경우 환경 변수에는 하나의 변수 만 포함됩니다. i
n
은 함수이므로 다음과 같이 호출 할 수 있습니다.
fmt.Println(n()) // 1
fmt.Println(n()) // 2
fmt.Println(n()) // 3
위의 출력에서 알 수 있듯이 n
이 호출 될 때마다 i
증가합니다. i
는 0에서 시작하고 n
호출하면 i++
실행됩니다.
i
의 값은 호출간에 유지됩니다. 즉, 폐쇄의 일부인 환경이 지속됩니다.
NaturalNumbers
다시 호출하면 새 함수가 만들어지고 반환됩니다. 그러면 NaturalNumbers
내에서 새 i
가 초기화됩니다. 즉, 새로 반환 된 함수가 함수 (여전히 f
)에 대한 동일한 부분을 가진 새로운 클로저를 형성하지만 완전히 새로운 환경 (새로 초기화 된 i
)을 의미합니다.
o := NaturalNumbers()
fmt.Println(n()) // 4
fmt.Println(o()) // 1
fmt.Println(o()) // 2
fmt.Println(n()) // 5
n
과 o
는 모두 동일한 함수 부분 (동일한 동작을 제공함)을 포함하지만 서로 다른 환경을 포함하는 클로저입니다. 따라서 클로저를 사용하면 함수가 호출간에 정보를 유지하는 데 사용할 수있는 영구 환경에 액세스 할 수 있습니다.
다른 예시:
func multiples(i int) func() int {
var x int = 0
return func() int {
x++
// paramenter to multiples (here it is i) also forms
// a part of the environment, and is retained
return x * i
}
}
two := multiples(2)
fmt.Println(two(), two(), two()) // 2 4 6
fortyTwo := multiples(42)
fmt.Println(fortyTwo(), fortyTwo(), fortyTwo()) // 42 84 126