Closure란
프로그래밍 언어에서 함수와 그 함수가 정의된 환경을 함께 포함한 개념입니다.
즉 클로저는 함수가 자유변수(Free Variable)에 접근할 수 있는 환경을 의미합니다.
음,,, 뭔가 말이 어렵죠?
클로저의 정의에서 외부함수, 내부함수, 자유변수의 개념만 이해하면 클로저를 쉽게 이해할 수
있으실 것 같아요
Closure의 정의
Closure는 함수 내부에서 정의된 함수(중첩함수)가 자신을 포함하는 외부 함수의 변수에 접근할 수
있는 기능을 제공한다
쉽게 말하자면 클로저는 함수 안에 함수가 정의되어 있는 중첩함수 구조이고
바깥에 있는 함수를 외부함수,
외부함수 내부에 정의된 함수를 내부함수라고 부릅니다.
자유변수는 외부함수에 선언되어 있지만 내부함수에서 접근가능한 변수를 말합니다.
Closure가 사용되는 상황
1. 내부 함수가 외부 함수의 변수를 유지하고 상태를 변경해야 할 때
2. 외부 함수의 변수를 공유하면서 여러 개의 내부 함수가 동작해야 할 때
3. 비동기 작업에서 콜백 함수 등을 사용할 때
사용법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
using System;
public class ClosureExample
{
//외부함수
public static Action<int> CreateCounter()
{
//자유변수
int counter = 0;
//내부함수
Action<int> increment = (x) =>
{
counter += x;
Console.WriteLine($"Counter: {counter}");
};
return increment;
}
public static void Main(string[] args)
{
var counter = CreateCounter();
counter(5); // Counter: 5
counter(3); // Counter: 8
counter(2); // Counter: 10
}
}
|
cs |
제가 .NET개발을 주로 하다 보니 예제코드도 C#으로 되어있지만
클로저의 개념은 JavaScript나 다른 언어들도 유사하기 때문에 개념만 이해하시면 될 것 같습니다.
예제코드를 보면 외부함수, 내부함수, 자유변수의 구조가 쉽게 파악되실 겁니다.
외부함수의 return값으로 내부함수인 increment를 내보내고 있습니다.
CreateCounter 메소드의 반환값(지금은 반환함수)을 변수에 담아두고
변수를 호출하는 방식으로 CreateCounter() 메소드를 호출하지 않아도
counter(5), counter(3) 처럼 내부함수를 바로 호출할 수 있게 됩니다.
신기한 점은 외부함수에 선언된 자유변수가 외부함수가 종료되도 반환되지 않고
남아있다는 것입니다.
counter(5), counter(3), counter(2) 를 호출할 때마다 console에 출력되는 값이
계속 더해지고 있는 것을 보실 수 있습니다.
궁금점
처음 클로저란 개념을 접했을 때 전역변수와 차이가 뭔지 이해가 안 됐습니다.
물론 둘은 전혀 다른 개념이지만 그때의 생각으로는 단순하게
외부함수에 있는 자유변수에 접근하지 말고 전역변수로 선언해서 사용하면 안 되나?
전역변수와 클로저 둘 다 변수에 접근하는 개념이지만, 중요한 차이점이 있습니다.
1. 범위(scope)
전역 변수는 프로그램 전체에서 접근 가능한 변수입니다. 즉 어디서든 사용할 수 있습니다.
반면에 클로저는 외부함수 내에서 정의된 변수에 접근 가능한 함수입니다.
클로저는 내부함수 범위에 한정되어 있으며, 내부함수를 호출하지 않고 외부에서는 접근할 수 없습니다.
2. 생명주기(lifeTime)
전역변수는 프로그램이 실행되는 동안 지속됩니다.
반면에 클로저는 클로저가 정의된 함수가 호출되고, 클로저 자체가 더 이상 참조되지 않을 때까지 유지됩니다.
함수가 호출될 때마다 새로운 클로저 인스턴스가 생성되며, 클로저가 참조하는 변수는 각각의 인스턴스에
저장됩니다.
3. 접근성(Accessibillity)
전역 변수는 프로그램의 어디서든 접근할 수 있기 때문에 여러 함수에서 공유할 수 있습니다.
클로저는 해당 함수 내부에서만 접근 가능하며, 외부에서 직접 접근할 수 없다.
클로저를 통해 외부 함수의 변수에 접근하려면 클로저를 반환하거나, 외부에서 호출 가능한 함수를 정의하여
접근해야 합니다.
4. 데이터 은닉(Data Encapsulation)
전역 변수는 어디서든 접근 가능하기 때문에 다른 부분에서 의도치 않게 변경될 수 있습니다.
반면에 클로저는 해당 함수 내부에서만 접근 가능하니 외부에서 변수에 직접 접근하지 못하고
내부 함수를 통해서만 변수에 접근할 수 있습니다.
이는 데이터의 은닉과 캡슐화를 촉진하여 프로그램의 안정성과 유지보수성을 향상시킬 수 있습니다.
전역변수는 주로 모듈 간의 데이터공유나 상태유지를 위해 사용되지만,
클로저는 함수 내부에서 변수의 값이 유지되어야 하는 경우나 비동기 작업 등 다양한 상황에서 사용됩니다.
정리
클로저는 중첩함수 구조이고 내부함수에서 외부함수의 자유변수에 접근가능하다.
원래 지역변수는 해당 함수가 종료되면 반환되지만, 클로저를 사용하면 외부함수가 종료되도
내부함수를 호출할 경우 외부함수의 자유변수에 접근가능하고, 자유변수는 반환되지 않고 상태가 유지된다.
이렇게 오늘은 클로저에 대해서 정리해 보았습니다.
감사합니다.