함수형 프로그래밍에 보면 반드시 껴있는 친구, 클로져(Closure)에 대해서 알아보겠습니다.
<이전 게시물 복습Time>
구글에게 물어보니 pyeswae 라고 하네요.
뭘 폐쇄한다는 건지?
잘은 모르겠는데, 폐쇄의 특징이 있는 것 같습니다.
{ ... } <- 이것처럼 코드블럭에 갇혀있는 상태
를 의미하는 것 같기도 하구요.
클로저 (Closure)는 코드블럭으로 C와 Objective-C의 블럭(blocks)과 다른 언어의 람다(lambdas)와 비슷 합니다. 클로저는 어떤 상수나 변수의 참조를 캡쳐(capture)해 저장할 수 있습니다. Swift는 이 캡쳐와 관련한 모든 메모리를 알아서 처리합니다.
- The Swift Language Guiude "클로저" 중에서 -
공식문서를 좀 해석해볼게요.
"전역 함수와 중첩함수는 실제로 클로저의 특별한 경우입니다." 클로저는 다음 세 가지 형태 중 하나를 갖습니다.
1. 전역함수 : 이름이 있고, 어떤 값도 캡처하지 않는 클로저
2. 중첩함수 : 이름이 있고 관련한 함수로부터 값을 캡처할 수 있는 클로저
3. 클로저 표현 : 경량화 된 문법으로 쓰이고 관련 문맥(Context)로 부터 값을 캡쳐할 수 있는 이름이 없는 클로저
클로저는 축약문법으로 다음 내용을 포함합니다.
- 문맥(Context)에서 인자 타입(Parameter type)과 반환 타입(return type)의 추론
- 단일 표현 클로저에서의 암시적 반환
- 축약된 인자 이름
- 후위 클로저 문법
여기까지는 제가 이전에 작성한 글과 다를 바없는 내용이므로 링크를 달아 두겠습니다.
https://velog.io/@kipsong/Swift-%ED%81%B4%EB%A1%9C%EC%A0%80%EC%9D%98-%EA%B8%B0%EB%B3%B8
복습끗
이번에는 이전글에서 다루지 않았던, "Capturing Valuse(값 캡쳐)" 부분을 다룰게요.
클로저는 특정 문맥의 "상수나 변수"의 값을 캡쳐할 수 있습니다.
= 원본 값이 사라져도 클로저의 body 안에서는 그 값을 활용할 수 있습니다.
가장 기본 형태가 중첩함수 (nested function)
입니다.
예시를 보겠습니다.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
(공식문서의 예제입니다.)
함수의 return이 조금 복잡하죠?
(forIncrement amount: Int) -> () -> Int
이렇게 보면 이해가 잘 안됩니다. 좀 나눠볼까요?
((forIncrement amount: Int)) -> (() -> Int)
조금 구분이 가시나요?
앞에 첫 번째 큰 괄호가 매개변수가 됩니다.
뒤에 두 번째 큰 괄호가 return type이 됩니다.
return 타입에 함수가 올 수 있음을 보여줍니다.
근데 함수 내부에 "incrementer()" 메소드를 보면 함수 내부에 "runnungTotal" 이라는 프로퍼티가 없음애도 접근하고 있죠.
한번 따로 보겠습니다.
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
이 메소드는 잘 돌아가고 있습니다. 메소드 코드블럭 내에 프로퍼티가 없어도요.
여기서 알 수 있는 점은 다음과 같습니다
runningTotal과 amount라는 값이 "캡처링" 되었구나!
이제 조금 값 캡쳐에 대한 느낌이 오시나요.
관련한 다른 예시는 다음 글에서 작성하겠습니다!