클로저란?
클로저는 외부 변수나 상태를 기억하고 쓸 수 있는 함수임.
함수가 만들어질 때 주변에 있던 변수들을 캡처해서 저장해 놓고, 나중에 다시 사용할 수 있게 해줌.
어떻게 동작함?
- 클로저는 자기 주변의 스코프(환경)를 기억함.
- 함수가 실행된 뒤에도 외부 변수의 상태를 유지함.
- 그래서 외부 변수를 읽거나 수정할 수 있음.
Dart에서 클로저 예제
1. 외부 변수를 기억하는 클로저
void main() {
int counter = 0;
Function increment = () {
counter++; // 외부 변수에 접근함
print("Counter: $counter");
};
increment(); // Counter: 1
increment(); // Counter: 2
}
- 함수
increment
는 외부 변수counter
를 기억하고 계속 사용함. - 실행할 때마다 외부 변수 값을 변경함.
2. 클로저를 반환하는 함수
Function makeMultiplier(int multiplier) {
return (int value) {
return value * multiplier; // multiplier를 기억함
};
}
void main() {
var doubleValue = makeMultiplier(2);
var tripleValue = makeMultiplier(3);
print(doubleValue(5)); // 10
print(tripleValue(5)); // 15
}
makeMultiplier
함수는 클로저를 반환함.- 반환된 함수는 외부 변수
multiplier
값을 기억하고, 그 값을 계속 사용함.
클로저의 장점
- 상태 유지:
- 함수가 실행된 후에도 외부 변수를 유지함.
- 외부 값을 저장하고 필요할 때 다시 사용 가능함.
- 코드 재사용성:
- 특정 상태와 동작을 캡슐화해서 어디서든 재사용할 수 있음.
- 캡슐화:
- 외부 변수는 클로저 안에서만 접근 가능함. 다른 코드에서는 수정할 수 없어서 안전함.
클로저는 어디에 쓰임?
- 상태 관리:
- 값이나 설정을 유지하면서 동작해야 할 때 사용함.
- 콜백 함수:
- 이벤트가 발생했을 때 특정 상태를 기반으로 동작할 때 사용함.
- 함수형 프로그래밍:
- Dart에서 고차 함수와 함께 사용될 때 강력한 도구가 됨.
익명 함수와 클로저의 정의
- 익명 함수:
- 이름이 없는 함수임.
- 그 자리에서 바로 정의하고 사용되는 함수.
- 외부 상태와 관계없이 독립적으로 작동할 수도 있음.
- 클로저:
- 외부 변수를 캡처해서 기억하고 사용하는 함수임.
- 익명 함수든, 이름 있는 함수든 외부 변수에 의존하면 클로저가 됨.
익명 함수와 클로저의 차이
구분 | 익명 함수 | 클로저 |
---|---|---|
이름 | 이름이 없음 | 이름이 있을 수도, 없을 수도 있음 |
외부 변수 캡처 | 외부 변수와 상관없이 독립적으로 사용 가능 | 외부 변수(스코프)를 기억하고 사용할 수 있음 |
사용 방식 | 콜백 함수나 일회성 작업에서 주로 사용 | 상태를 저장하고 재사용해야 하는 작업에서 사용 |
관계 | 클로저가 될 수도 있음 (외부 변수를 캡처하면 클로저로 작동함) | 익명 함수, 이름 있는 함수 모두 클로저가 될 수 있음 |
코드 예제로 이해하기
1. 익명 함수 (클로저 아님)
외부 변수에 의존하지 않음. 그냥 이름 없는 함수임.
void main() {
var add = (int a, int b) {
return a + b;
};
print(add(3, 4)); // 7
}
- 익명 함수: 외부 변수와 관계없이 동작함. 외부 상태를 기억하지 않으므로 클로저가 아님.
2. 클로저 (외부 변수 캡처)
외부 변수(count
)를 기억해서 사용하는 함수임.
void main() {
int count = 0;
var increment = () {
count++; // 외부 변수 사용
print("Counter: $count");
};
increment(); // Counter: 1
increment(); // Counter: 2
}
- 클로저: 익명 함수가 외부 변수
count
를 캡처해서 상태를 유지함.
3. 이름 있는 클로저
익명 함수가 아니어도 클로저가 될 수 있음.
Function makeMultiplier(int multiplier) {
return (int value) {
return value * multiplier; // 외부 변수 multiplier 캡처
};
}
void main() {
var doubleValue = makeMultiplier(2); // multiplier = 2
print(doubleValue(5)); // 10
}
- 반환된 함수는 이름이 없지만, 여전히 외부 변수
multiplier
를 캡처해서 사용하는 클로저임.
익명 함수는 언제 클로저가 될까?
익명 함수가 외부 변수를 참조할 때 클로저가 됨.
즉, 모든 익명 함수가 클로저는 아님!
예제:
void main() {
int x = 10;
// 클로저
var closure = () {
print("x는 $x임");
};
closure(); // x는 10임
}
- 여기서 익명 함수
closure
는 외부 변수x
를 참조하므로 클로저임.
왕깔끔정리
외부변수에 의존하면. 클로저임 클로저는 캡쳐를 하닝까
'Flutter > Dart' 카테고리의 다른 글
static GetIt get instance => _instance; <-- 여기에 쓰인 문법을 모두 설명해보세요. (0) | 2024.10.14 |
---|---|
멤버 변수 vs 상태 (0) | 2024.10.14 |
fromMap을 사용해 map데이터 쉽게 사용하기 (0) | 2024.09.19 |
Stream, Future 둘의 차이점은 뭐지? (2) | 2024.08.12 |
Enum이 뭐고, Enhanced Enum은 왜 쓸까? (0) | 2024.08.12 |