https://docs.swift.org/swift-book/LanguageGuide/Functions.html#ID178
스위프트 공식문서의 Functions 챕터에도 나오지만 흔히 말하는 함수는 대부분 글로벌 함수일 것이다. 어디서나 호출할 수 있는 함수이다(global scope).
중첩 함수는 이름처럼 함수 안에 작성하는 함수를 말한다. 아래처럼 chooseStepFunction 함수(글로벌 함수) 안에 작성된 함수들이 모두 중첩 함수 nested function이다. chooseStepFunction 함수는 chooseStepFunction() 처럼 호출할 수 있지만 중첩 함수들은 chooseStepFunction 함수 안에서만 호출할 수 있다.
// 출처: https://docs.swift.org/swift-book/LanguageGuide/Functions.html#ID178
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backward ? stepBackward : stepForward
}
대신 이 중첩 함수들을 리턴값으로 반환하여 사용할 수 있다.
// 출처: https://docs.swift.org/swift-book/LanguageGuide/Functions.html#ID178
var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
// 중첩 함수 stepForward를 변수 moveNearerToZero에 할당하여 아래와 같이 사용할 수 있다.
while currentValue != 0 {
print("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue) // moveNearerToZero 호출
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!
이 뿐만 아니라 중첩 함수는 자신을 감싸고 있는 바깥 함수의 값들을 '캡쳐링' 할 수 있다. (...can capture values from their enclosing function - 출처: https://docs.swift.org/swift-book/LanguageGuide/Closures.html) 바깥 함수에서 선언한 constants, variables 외에 arguments도 캡쳐링 할 수 있다. 중첩 함수 내부에서 바깥 함수의 값을 읽거나 수정할 수 있다. 바깥 함수가 사라져도 가능하다. 그러므로 '캡쳐링' 이란 자기 자신의 바깥에 선언된 값들을 읽거나 수정할 수 있는데, 그 바깥 환경이 사라져도 역시 읽거나 수정이 가능하게 하는 성질(?)이라고 정리할 수 있을 것 같다.
그래서 이 '캡쳐링'을 테스트 해보기 위해 위의 예제를 약간 바꿔봤는데,
func chooseStepFunction(backward: Bool) -> () -> Void {
var count = 0
func stepForward() {
count += 5
print("count stepForward: \(count)")
}
func stepBackward() {
count += 7
print("count stepBackward: \(count)")
}
return backward ? stepBackward : stepForward
}
var currentValue = -4
let moveBackword = chooseStepFunction(backward: true)
let moveForword = chooseStepFunction(backward: false)
moveBackword() // 7
moveForword() // 5
moveBackword() // 14
moveBackword() // 21
moveForword() // 10
chooseStepFunction이 중첩 함수를 리턴하고 사라진 후에도 count 변수를 계속 수정하는 것을 볼 수 있다.
'swift & iOS > swift' 카테고리의 다른 글
[swift] 옵셔널 optional 타입을 다루는 5가지 방법 (0) | 2022.01.20 |
---|---|
[swift] 소수점 둘째 자리 까지 나타내기 (feat. round(), String) (0) | 2022.01.20 |
parameter vs argument (0) | 2022.01.16 |
[swift] 클로저 closure (feat. 함수) (0) | 2022.01.16 |
[swift] 함수에 함수를 전달하거나 함수를 리턴하거나 (0) | 2022.01.16 |