클로저(Closure)
람다 표현식에서 ()는 람다 식 자체가 매개 변수를 받지 않는다는 의미일 뿐, 람다 내부에서 사용하는 변수들이 반드시 람다 표현식의 매개 변수로 전달되어야 하는 것은 아닙니다.
람다 내부에서는 외부에서 정의된 변수를 그대로 사용할 수 있습니다.
이 때, 외부 변수를 캡처하여 사용하는 것을 **클로저(Closure)**라고 부릅니다.
즉, () => zombies.Remove(zombie) 이런 코드가 있다고 가정할 때,
()는 람다 표현식 자체에 매개 변수가 없다는 의미입니다.
그러나, 람다 표현식 내부에서는 외부의 zombie 변수를 사용하고 있습니다.
이 zombie는 이미 람다 표현식 바깥에서 선언된 변수이며, 함수 호출에 필요한 매개 변수로 그대로 사용될 수 있습니다.
Zombie zombie = new Zombie();
zombie.onDeath += () => zombies.Remove(zombie);
이 코드에서 zombie 변수는 람다 표현식 외부에서 정의된 변수입니다.
() => zombies.Remove(zombie)는 매개 변수를 받지 않는 람다 표현식입니다.
하지만 람다 표현식 내부에서는 외부에 선언된 zombie 변수를 사용하고 있기 때문에, 마치 해당 변수가 매개 변수인 것처럼 동작합니다.
즉, 이 zombie는 이미 해당 코드 범위에서 선언된 변수이므로, 이를 따로 매개 변수로 넘길 필요가 없습니다.
이 경우, 람다 표현식 내부에서 사용하는 zombie는 이미 외부에서 선언된 변수이므로, zombies.Remove(zombie)가 호출될 때, Remove() 함수는 정상적으로 zombie를 인자로 받습니다.
매개 변수가 없는 람다 표현식과 외부 변수 사용의 관계
람다 표현식에서 매개 변수가 없다고 하더라도, 그 내부에서 외부 범위에 존재하는 변수를 참조할 수 있습니다. 이를 통해 매개 변수를 굳이 직접 전달하지 않고도, 외부 변수를 사용하는 코드가 가능합니다.
zombie.onDeath += () => zombies.Remove(zombie);
다시 말해 ()는 이 람다 표현식이 새로운 매개 변수를 받지 않음을 의미합니다.
그러나 외부에 이미 선언된 zombie 변수는 해당 람다 표현식 내부에서 자유롭게 사용됩니다.
따라서 Remove()는 zombie라는 매개 변수를 받지만, 이 zombie는 외부에 정의된 변수이므로 별도로 전달할 필요 없이 바로 사용이 가능합니다.
결론
() => zombies.Remove(zombie)에서 ()는 매개 변수가 없다는 의미지만, 외부 변수 zombie는 클로저를 통해 캡처되어 그대로 사용됩니다.
이 덕분에 Remove(zombie)는 정상적으로 zombie 객체를 인자로 받을 수 있습니다.
클로저를 사용하면 매개 변수를 명시하지 않아도 외부 변수를 내부에서 참조할 수 있기 때문에 가능한 동작입니다.
'프로그래밍 > C#' 카테고리의 다른 글
구조체의 new (0) | 2024.11.29 |
---|---|
Action 의 다양한 형태들 (0) | 2024.10.19 |
delegate 표현 방식들 (1) | 2024.10.19 |
delegate 와 Action 그리고 Func (0) | 2024.10.19 |
클로저 (Closure) (0) | 2024.10.19 |